summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcvs2hg <devnull@localhost>2000-02-18 16:17:40 +0000
committercvs2hg <devnull@localhost>2000-02-18 16:17:40 +0000
commit482204d6082266d6cbeef405bdf15c477c0f0df7 (patch)
tree4e86dac6e660d3d22127c47a0d271aebcad9f7ed
parentdd3a7d760e718ea6f09dd4adb525453da70cd153 (diff)
downloadnspr-hg-travisWebshell_20000308_BRANCH.tar.gz
fixup commit for branch 'travisWebshell_20000308_BRANCH'travisWebshell_20000308_BRANCH
-rw-r--r--Makefile2
-rw-r--r--Makefile.in2
-rw-r--r--config/Linux.mk2
-rw-r--r--config/module.df2
-rw-r--r--config/prdepend.h26
-rw-r--r--config/rules.mk25
-rwxr-xr-xconfigure76
-rw-r--r--configure.in3
-rw-r--r--lib/Makefile4
-rw-r--r--lib/Makefile.in4
-rw-r--r--lib/ds/MANIFEST1
-rw-r--r--lib/ds/Makefile2
-rw-r--r--lib/ds/Makefile.in2
-rw-r--r--lib/ds/plds.rc6
-rw-r--r--lib/ds/plevent.c1087
-rw-r--r--lib/ds/plevent.h497
-rw-r--r--lib/ds/plvrsion.c11
-rw-r--r--lib/libc/src/plc.rc6
-rw-r--r--lib/libc/src/plvrsion.c11
-rw-r--r--lib/prstreams/plvrsion.c11
-rw-r--r--lib/prstreams/prstrms.cpp2
-rw-r--r--lib/prstreams/prstrms.h8
-rw-r--r--lib/prstreams/prstrms.rc6
-rw-r--r--macbuild/NSPR20PPC.mcpbin97817 -> 97889 bytes
-rw-r--r--makefile.win5
-rw-r--r--pr/include/MANIFEST3
-rw-r--r--pr/include/md/_aix.h1
-rw-r--r--pr/include/md/_aix32.cfg2
-rw-r--r--pr/include/md/_aix32in6.cfg1
-rw-r--r--pr/include/md/_aix64.cfg1
-rw-r--r--pr/include/md/_beos.h2
-rw-r--r--pr/include/md/_hpux.h1
-rw-r--r--pr/include/md/_hpux32.cfg2
-rw-r--r--pr/include/md/_hpux64.cfg2
-rw-r--r--pr/include/md/_irix.h1
-rw-r--r--pr/include/md/_irix32.cfg2
-rw-r--r--pr/include/md/_irix64.cfg2
-rw-r--r--pr/include/md/_linux.cfg2
-rw-r--r--pr/include/md/_linux.h4
-rw-r--r--pr/include/md/_macos.h2
-rw-r--r--pr/include/md/_os2.h2
-rw-r--r--pr/include/md/_osf1.cfg2
-rw-r--r--pr/include/md/_osf1.h7
-rw-r--r--pr/include/md/_solaris.h9
-rw-r--r--pr/include/md/_solaris32.cfg2
-rw-r--r--pr/include/md/_solaris64.cfg2
-rw-r--r--pr/include/md/_unixos.h4
-rw-r--r--pr/include/md/_unixware7.cfg2
-rw-r--r--pr/include/md/_win95.cfg2
-rw-r--r--pr/include/md/_win95.h15
-rw-r--r--pr/include/md/_winnt.cfg2
-rw-r--r--pr/include/md/_winnt.h15
-rw-r--r--pr/include/nspr.h2
-rw-r--r--pr/include/obsolete/probslet.h69
-rw-r--r--pr/include/obsolete/protypes.h28
-rw-r--r--pr/include/prerr.h4
-rw-r--r--pr/include/prinit.h7
-rw-r--r--pr/include/prio.h117
-rw-r--r--pr/include/pripcsem.h1
-rw-r--r--pr/include/private/pprio.h21
-rw-r--r--pr/include/private/primpl.h45
-rw-r--r--pr/include/prlink_mac.h66
-rw-r--r--pr/include/prlog.h6
-rw-r--r--pr/include/prlong.h8
-rw-r--r--pr/include/prnetdb.h66
-rw-r--r--pr/include/prrng.h42
-rw-r--r--pr/include/prshm.h1
-rw-r--r--pr/include/prtpool.h46
-rwxr-xr-xpr/include/prvrsion.h14
-rw-r--r--pr/src/Makefile9
-rw-r--r--pr/src/Makefile.in5
-rw-r--r--pr/src/io/Makefile5
-rw-r--r--pr/src/io/Makefile.in5
-rw-r--r--pr/src/io/prdir.c12
-rw-r--r--pr/src/io/prfdcach.c4
-rw-r--r--pr/src/io/prfile.c28
-rw-r--r--pr/src/io/priometh.c24
-rw-r--r--pr/src/io/pripv6.c336
-rw-r--r--pr/src/io/prlayer.c22
-rw-r--r--pr/src/io/prpolevt.c4
-rw-r--r--pr/src/io/prsocket.c281
-rw-r--r--pr/src/linking/prlink.c27
-rw-r--r--pr/src/md/mac/macsocket.h2
-rw-r--r--pr/src/md/mac/macsockotpt.c56
-rw-r--r--pr/src/md/mac/prcpucfg.h2
-rw-r--r--pr/src/md/windows/Makefile2
-rw-r--r--pr/src/md/windows/ntio.c388
-rw-r--r--pr/src/md/windows/ntsec.c252
-rw-r--r--pr/src/md/windows/ntthread.c2
-rw-r--r--pr/src/md/windows/w32ipcsem.c35
-rw-r--r--pr/src/md/windows/w32shm.c36
-rw-r--r--pr/src/md/windows/w95io.c126
-rw-r--r--pr/src/md/windows/w95thred.c2
-rw-r--r--pr/src/md/windows/win32_errors.c3
-rw-r--r--pr/src/misc/prerr.c2
-rw-r--r--pr/src/misc/prerr.et2
-rw-r--r--pr/src/misc/prerr.properties2
-rw-r--r--pr/src/misc/prerror.c6
-rw-r--r--pr/src/misc/prinit.c20
-rw-r--r--pr/src/misc/prnetdb.c812
-rw-r--r--pr/src/misc/prtpool.c303
-rw-r--r--pr/src/nspr.rc6
-rw-r--r--pr/src/prvrsion.c11
-rw-r--r--pr/src/pthreads/ptio.c1290
-rw-r--r--pr/src/pthreads/ptsynch.c2
-rw-r--r--pr/src/pthreads/ptthread.c27
-rw-r--r--pr/tests/Makefile5
-rw-r--r--pr/tests/Makefile.in4
-rw-r--r--pr/tests/accept.c2
-rw-r--r--pr/tests/acceptread.c2
-rw-r--r--pr/tests/addrstr.c95
-rw-r--r--pr/tests/affinity.c1
-rw-r--r--pr/tests/cltsrv.c28
-rw-r--r--pr/tests/gethost.c101
-rw-r--r--pr/tests/ipv6.c20
-rw-r--r--pr/tests/lltest.c112
-rw-r--r--pr/tests/makedir.c80
-rw-r--r--pr/tests/mbcs.c168
-rw-r--r--pr/tests/nonblock.c15
-rw-r--r--pr/tests/ntioto.c12
-rw-r--r--pr/tests/ntoh.c106
-rw-r--r--pr/tests/op_excl.c2
-rw-r--r--pr/tests/openfile.c126
-rw-r--r--pr/tests/poll_nm.c8
-rw-r--r--pr/tests/provider.c9
-rwxr-xr-xpr/tests/runtests.ksh89
-rw-r--r--pr/tests/sema.c4
-rw-r--r--pr/tests/semaping.c6
-rw-r--r--pr/tests/semapong.c6
-rw-r--r--pr/tests/server_test.c4
-rw-r--r--pr/tests/servr_kk.c4
-rw-r--r--pr/tests/servr_ku.c4
-rw-r--r--pr/tests/servr_uk.c4
-rw-r--r--pr/tests/servr_uu.c4
-rw-r--r--pr/tests/socket.c155
-rw-r--r--pr/tests/sockopt.c73
-rw-r--r--pr/tests/thrpool_client.c1
-rw-r--r--pr/tests/thrpool_server.c79
-rw-r--r--pr/tests/thruput.c5
-rw-r--r--pr/tests/tmoacc.c4
-rw-r--r--pr/tests/tmocon.c3
-rw-r--r--pr/tests/vercheck.c17
-rw-r--r--pr/tests/version.c2
143 files changed, 3886 insertions, 4061 deletions
diff --git a/Makefile b/Makefile
index f31dc7fc..e92f2d40 100644
--- a/Makefile
+++ b/Makefile
@@ -101,5 +101,5 @@ endif
cp -f mdheader.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \
chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/mdheader.jar
-depend: clean
+depend:
@echo "NSPR20 has no dependencies. Skipped."
diff --git a/Makefile.in b/Makefile.in
index 11ffcee9..8ff221b8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -106,5 +106,5 @@ endif
cp -f mdheader.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \
chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/mdheader.jar
-depend: clean
+depend:
@echo "NSPR20 has no dependencies. Skipped."
diff --git a/config/Linux.mk b/config/Linux.mk
index 21c85ebc..29832d08 100644
--- a/config/Linux.mk
+++ b/config/Linux.mk
@@ -47,6 +47,8 @@ IMPL_STRATEGY = _PTH
DEFINES += -D_REENTRANT
endif
+USE_IPV6 = 1
+
ifeq (86,$(findstring 86,$(OS_TEST)))
CPU_ARCH := x86
else
diff --git a/config/module.df b/config/module.df
index 126476b5..04522daf 100644
--- a/config/module.df
+++ b/config/module.df
@@ -20,4 +20,4 @@
# A module is also called a component or a subsystem.
MOD_NAME = nspr20
-MOD_VERSION = 3
+MOD_VERSION = 4
diff --git a/config/prdepend.h b/config/prdepend.h
new file mode 100644
index 00000000..e95d6f92
--- /dev/null
+++ b/config/prdepend.h
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 2000 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+/*
+ * A dummy header file that is a dependency for all the object files.
+ * Used to force a full recompilation of NSPR in Mozilla's Tinderbox
+ * depend builds. See comments in rules.mk.
+ */
+
+#error "Do not include this header file."
+
diff --git a/config/rules.mk b/config/rules.mk
index 4b5829c3..476ea0ea 100644
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -62,12 +62,14 @@ endif
ifdef USE_AUTOCONF
ifdef INTERNAL_TOOLS
+ifdef CROSS_COMPILE
CC=$(HOST_CC)
CCC=$(HOST_CXX)
CFLAGS=$(HOST_CFLAGS)
CXXFLAGS=$(HOST_CXXFLAGS)
endif
endif
+endif
#
# This makefile contains rules for building the following kinds of
@@ -408,6 +410,29 @@ $(OBJDIR)/%.$(OBJ_SUFFIX): %.s
%: %.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.
################################################################################
diff --git a/configure b/configure
index 6c931075..0496847f 100755
--- a/configure
+++ b/configure
@@ -693,7 +693,7 @@ cat >> confdefs.h <<\EOF
EOF
-NSPR_VERSION=3
+NSPR_VERSION=4
NSPR_MODNAME=nspr20
_HAVE_PTHREADS=
USE_PTHREADS=
@@ -2785,6 +2785,10 @@ EOF
#define _SVID_SOURCE 1
EOF
+ cat >> confdefs.h <<\EOF
+#define LINUX 1
+EOF
+
CFLAGS="$CFLAGS -pipe -ansi"
CXXFLAGS="$CXXFLAGS -pipe -ansi"
MDCPUCFG_H=_linux.cfg
@@ -3024,7 +3028,7 @@ fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:3028: checking how to run the C preprocessor" >&5
+echo "configure:3032: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -3039,13 +3043,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 3043 "configure"
+#line 3047 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3049: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3053: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -3056,13 +3060,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 3060 "configure"
+#line 3064 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3066: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3070: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -3073,13 +3077,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 3077 "configure"
+#line 3081 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3083: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3087: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -3105,13 +3109,13 @@ echo "$ac_t""$CPP" 1>&6
if test $ac_cv_prog_gcc = yes; then
echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
-echo "configure:3109: checking whether ${CC-cc} needs -traditional" >&5
+echo "configure:3113: checking whether ${CC-cc} needs -traditional" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_pattern="Autoconf.*'x'"
cat > conftest.$ac_ext <<EOF
-#line 3115 "configure"
+#line 3119 "configure"
#include "confdefs.h"
#include <sgtty.h>
Autoconf TIOCGETP
@@ -3129,7 +3133,7 @@ rm -f conftest*
if test $ac_cv_prog_gcc_traditional = no; then
cat > conftest.$ac_ext <<EOF
-#line 3133 "configure"
+#line 3137 "configure"
#include "confdefs.h"
#include <termio.h>
Autoconf TCGETA
@@ -3153,12 +3157,12 @@ fi
for ac_func in lchown strerror
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3157: checking for $ac_func" >&5
+echo "configure:3161: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3162 "configure"
+#line 3166 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -3181,7 +3185,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:3185: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3189: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -3209,7 +3213,7 @@ done
echo $ac_n "checking for pthread_attr_init in -lpthread""... $ac_c" 1>&6
-echo "configure:3213: checking for pthread_attr_init in -lpthread" >&5
+echo "configure:3217: checking for pthread_attr_init in -lpthread" >&5
ac_lib_var=`echo pthread'_'pthread_attr_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3217,7 +3221,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lpthread $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3221 "configure"
+#line 3225 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3228,7 +3232,7 @@ int main() {
pthread_attr_init()
; return 0; }
EOF
-if { (eval echo configure:3232: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3236: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3247,7 +3251,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for pthread_attr_init in -lc_r""... $ac_c" 1>&6
-echo "configure:3251: checking for pthread_attr_init in -lc_r" >&5
+echo "configure:3255: checking for pthread_attr_init in -lc_r" >&5
ac_lib_var=`echo c_r'_'pthread_attr_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3255,7 +3259,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lc_r $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3259 "configure"
+#line 3263 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3266,7 +3270,7 @@ int main() {
pthread_attr_init()
; return 0; }
EOF
-if { (eval echo configure:3270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3285,7 +3289,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for pthread_attr_init in -lc""... $ac_c" 1>&6
-echo "configure:3289: checking for pthread_attr_init in -lc" >&5
+echo "configure:3293: checking for pthread_attr_init in -lc" >&5
ac_lib_var=`echo c'_'pthread_attr_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3293,7 +3297,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lc $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3297 "configure"
+#line 3301 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3304,7 +3308,7 @@ int main() {
pthread_attr_init()
; return 0; }
EOF
-if { (eval echo configure:3308: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3312: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3431,7 +3435,7 @@ if test -n "$USE_PTHREADS"; then
rm -f conftest*
ac_cv_have_dash_pthread=no
echo $ac_n "checking whether ${CC-cc} accepts -pthread""... $ac_c" 1>&6
-echo "configure:3435: checking whether ${CC-cc} accepts -pthread" >&5
+echo "configure:3439: checking whether ${CC-cc} accepts -pthread" >&5
echo 'int main() { return 0; }' | cat > conftest.c
${CC-cc} -pthread -o conftest conftest.c > conftest.out 2>&1
if test $? -eq 0; then
@@ -3501,12 +3505,12 @@ EOF
esac
echo $ac_n "checking for pthread_create""... $ac_c" 1>&6
-echo "configure:3505: checking for pthread_create" >&5
+echo "configure:3509: checking for pthread_create" >&5
if eval "test \"`echo '$''{'ac_cv_func_pthread_create'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3510 "configure"
+#line 3514 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char pthread_create(); below. */
@@ -3529,7 +3533,7 @@ pthread_create();
; return 0; }
EOF
-if { (eval echo configure:3533: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3537: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_pthread_create=yes"
else
@@ -3548,7 +3552,7 @@ else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
-echo "configure:3552: checking for pthread_create in -lpthread" >&5
+echo "configure:3556: checking for pthread_create in -lpthread" >&5
ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3556,7 +3560,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lpthread $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3560 "configure"
+#line 3564 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3567,7 +3571,7 @@ int main() {
pthread_create()
; return 0; }
EOF
-if { (eval echo configure:3571: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3666,12 +3670,12 @@ EOF
esac
echo $ac_n "checking for dlopen""... $ac_c" 1>&6
-echo "configure:3670: checking for dlopen" >&5
+echo "configure:3674: checking for dlopen" >&5
if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3675 "configure"
+#line 3679 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char dlopen(); below. */
@@ -3694,7 +3698,7 @@ dlopen();
; return 0; }
EOF
-if { (eval echo configure:3698: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_dlopen=yes"
else
@@ -3713,7 +3717,7 @@ else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
-echo "configure:3717: checking for dlopen in -ldl" >&5
+echo "configure:3721: checking for dlopen in -ldl" >&5
ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3721,7 +3725,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-ldl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3725 "configure"
+#line 3729 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3732,7 +3736,7 @@ int main() {
dlopen()
; return 0; }
EOF
-if { (eval echo configure:3736: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
diff --git a/configure.in b/configure.in
index 450e0502..1f2db5d4 100644
--- a/configure.in
+++ b/configure.in
@@ -40,7 +40,7 @@ AC_DEFINE(USE_AUTOCONF)
dnl ========================================================
dnl = Defaults
dnl ========================================================
-NSPR_VERSION=3
+NSPR_VERSION=4
NSPR_MODNAME=nspr20
_HAVE_PTHREADS=
USE_PTHREADS=
@@ -555,6 +555,7 @@ case "$target" in
AC_DEFINE(_POSIX_SOURCE)
AC_DEFINE(_BSD_SOURCE)
AC_DEFINE(_SVID_SOURCE)
+ AC_DEFINE(LINUX)
CFLAGS="$CFLAGS -pipe -ansi"
CXXFLAGS="$CXXFLAGS -pipe -ansi"
MDCPUCFG_H=_linux.cfg
diff --git a/lib/Makefile b/lib/Makefile
index 503670a7..9bb7d95c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -25,10 +25,6 @@ include $(MOD_DEPTH)/config/config.mk
DIRS = ds libc
-ifneq (,$(filter-out Rhapsody WIN16 NEWS-OS,$(OS_TARGET)))
-DIRS += prstreams
-endif
-
include $(MOD_DEPTH)/config/rules.mk
export:: $(TARGETS)
diff --git a/lib/Makefile.in b/lib/Makefile.in
index ff842c69..e6a1c312 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -30,10 +30,6 @@ include $(topsrcdir)/config/config.mk
DIRS = ds libc
-ifneq (,$(filter-out Rhapsody WIN16 NEWS-OS,$(OS_TARGET)))
-DIRS += prstreams
-endif
-
include $(topsrcdir)/config/rules.mk
export:: $(TARGETS)
diff --git a/lib/ds/MANIFEST b/lib/ds/MANIFEST
index ce8226bd..ceda33b7 100644
--- a/lib/ds/MANIFEST
+++ b/lib/ds/MANIFEST
@@ -4,5 +4,4 @@
plarenas.h
plarena.h
-plevent.h
plhash.h
diff --git a/lib/ds/Makefile b/lib/ds/Makefile
index b3076f3c..2c5881d0 100644
--- a/lib/ds/Makefile
+++ b/lib/ds/Makefile
@@ -32,7 +32,6 @@ INCLUDES = -I$(DIST)/include -I$(MOD_DEPTH)/pr/include
CSRCS = \
plarena.c \
- plevent.c \
plhash.c \
plvrsion.c \
$(NULL)
@@ -40,7 +39,6 @@ CSRCS = \
HEADERS = \
plarenas.h \
plarena.h \
- plevent.h \
plhash.h \
$(NULL)
diff --git a/lib/ds/Makefile.in b/lib/ds/Makefile.in
index 6c87443d..0240723c 100644
--- a/lib/ds/Makefile.in
+++ b/lib/ds/Makefile.in
@@ -39,7 +39,6 @@ INCLUDES = -I$(DIST)/include -I$(topsrcdir)/pr/include
CSRCS = \
plarena.c \
- plevent.c \
plhash.c \
plvrsion.c \
$(NULL)
@@ -47,7 +46,6 @@ CSRCS = \
HEADERS = \
plarenas.h \
plarena.h \
- plevent.h \
plhash.h \
$(NULL)
diff --git a/lib/ds/plds.rc b/lib/ds/plds.rc
index c9aceae8..10311c0a 100644
--- a/lib/ds/plds.rc
+++ b/lib/ds/plds.rc
@@ -22,6 +22,10 @@
#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
@@ -66,7 +70,7 @@ BEGIN
VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
VALUE "FileVersion", PR_VERSION "\0"
VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "LegalCopyright", "Copyright \251 1996-1999 Netscape Communications Corporation\0"
+ VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
VALUE "ProductName", "Netscape Portable Runtime\0"
VALUE "ProductVersion", PR_VERSION "\0"
diff --git a/lib/ds/plevent.c b/lib/ds/plevent.c
deleted file mode 100644
index ba7deedf..00000000
--- a/lib/ds/plevent.c
+++ /dev/null
@@ -1,1087 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*
- * The contents of this file are subject to the Netscape Public License
- * Version 1.1 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
-#if defined(_WIN32) || defined(WIN16)
-#include <windows.h>
-#endif
-
-#if defined(XP_OS2)
-#define INCL_WIN
-#include <os2.h>
-#define DefWindowProc WinDefWindowProc
-typedef MPARAM WPARAM,LPARAM;
-#endif /* XP_OS2 */
-
-#include "nspr.h"
-#include "plevent.h"
-
-#if !defined(WIN32)
-#include <errno.h>
-#include <stddef.h>
-#if !defined(XP_OS2)
-#include <unistd.h>
-#endif /* !XP_OS2 */
-#endif /* !Win32 */
-
-#if defined(XP_UNIX)
-/* for fcntl */
-#include <sys/types.h>
-#include <fcntl.h>
-#endif
-
-#if defined(XP_BEOS)
-#include <kernel/OS.h>
-#endif
-
-#if defined(XP_MAC)
-#include <AppleEvents.h>
-#include "pprthred.h"
-#else
-#include "private/pprthred.h"
-#endif /* XP_MAC */
-
-#if defined(VMS)
-/*
-** On OpenVMS, XtAppAddInput doesn't want a regular fd, instead it
-** wants an event flag. So, we don't create and use a pipe for
-** notification of when an event queue has something ready, instead
-** we use an event flag. Shouldn't be a problem if we only have
-** a few event queues.
-*/
-#include <lib$routines.h>
-#include <starlet.h>
-#include <stsdef.h>
-#endif /* VMS */
-
-
-static PRLogModuleInfo *event_lm = NULL;
-
-/*******************************************************************************
- * Private Stuff
- ******************************************************************************/
-
-/*
-** EventQueueType -- Defines notification type for an event queue
-**
-*/
-typedef enum
-{
- EventQueueIsNative = 1,
- EventQueueIsMonitored = 2
-} EventQueueType;
-
-
-struct PLEventQueue {
- char* name;
- PRCList queue;
- PRMonitor* monitor;
- PRThread* handlerThread;
- EventQueueType type;
- PRBool processingEvents;
-#if defined(VMS)
- int efn;
- int notifyCount;
-#elif defined(XP_UNIX)
- PRInt32 eventPipe[2];
- int notifyCount;
-#elif defined(_WIN32) || defined(WIN16)
- HWND eventReceiverWindow;
-#elif defined(XP_OS2)
- HWND eventReceiverWindow;
-#elif defined(XP_BEOS)
- port_id eventport;
-#endif
-};
-
-#define PR_EVENT_PTR(_qp) \
- ((PLEvent*) ((char*) (_qp) - offsetof(PLEvent, link)))
-
-static PRStatus _pl_SetupNativeNotifier(PLEventQueue* self);
-static void _pl_CleanupNativeNotifier(PLEventQueue* self);
-static PRStatus _pl_NativeNotify(PLEventQueue* self);
-static PRStatus _pl_AcknowledgeNativeNotify(PLEventQueue* self);
-static void _md_CreateEventQueue( PLEventQueue *eventQueue );
-static PRInt32 _pl_GetEventCount(PLEventQueue* self);
-
-
-#if defined(_WIN32) || defined(WIN16) || defined(XP_OS2)
-#if defined(XP_OS2)
-ULONG _pr_PostEventMsgId;
-static char *_pr_eventWindowClass = "NSPR:EventWindow";
-#else
-UINT _pr_PostEventMsgId;
-static char *_pr_eventWindowClass = "NSPR:EventWindow";
-#endif /* OS2 */
-#endif /* Win32, Win16, OS2 */
-
-/*******************************************************************************
- * Event Queue Operations
- ******************************************************************************/
-
-/*
-** _pl_CreateEventQueue() -- Create the event queue
-**
-**
-*/
-static PLEventQueue *
- _pl_CreateEventQueue(
- char *name,
- PRThread *handlerThread,
- EventQueueType qtype
-)
-{
- PRStatus err;
- PLEventQueue* self = NULL;
- PRMonitor* mon = NULL;
-
- if (event_lm == NULL)
- event_lm = PR_NewLogModule("event");
-
- self = PR_NEWZAP(PLEventQueue);
- if (self == NULL) return NULL;
-
- mon = PR_NewNamedMonitor(name);
- if (mon == NULL) goto error;
-
- self->name = name;
- self->monitor = mon;
- self->handlerThread = handlerThread;
- self->processingEvents = PR_FALSE;
- self->type = qtype;
- PR_INIT_CLIST(&self->queue);
- if ( qtype == EventQueueIsNative )
- {
- err = _pl_SetupNativeNotifier(self);
- if (err) goto error;
- }
- _md_CreateEventQueue( self );
- return self;
-
- error:
- if (mon != NULL)
- PR_DestroyMonitor(mon);
- PR_DELETE(self);
- return NULL;
-} /* end _pl_CreateEventQueue() */
-
-
-PR_IMPLEMENT(PLEventQueue*)
-PL_CreateEventQueue(char* name, PRThread* handlerThread)
-{
- return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsNative ));
-}
-
-PR_EXTERN(PLEventQueue *)
- PL_CreateNativeEventQueue(
- char *name,
- PRThread *handlerThread
- )
-{
- return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsNative ));
-} /* --- end PL_CreateNativeEventQueue() --- */
-
-PR_EXTERN(PLEventQueue *)
- PL_CreateMonitoredEventQueue(
- char *name,
- PRThread *handlerThread
- )
-{
- return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsMonitored ));
-} /* --- end PL_CreateMonitoredEventQueue() --- */
-
-
-
-PR_IMPLEMENT(PRMonitor*)
-PL_GetEventQueueMonitor(PLEventQueue* self)
-{
- return self->monitor;
-}
-
-static void PR_CALLBACK
-_pl_destroyEvent(PLEvent* event, void* data, PLEventQueue* queue)
-{
-#ifdef XP_MAC
-#pragma unused (data, queue)
-#endif
- PL_DequeueEvent(event, queue);
- PL_DestroyEvent(event);
-}
-
-PR_IMPLEMENT(void)
-PL_DestroyEventQueue(PLEventQueue* self)
-{
- PR_EnterMonitor(self->monitor);
-
- /* destroy undelivered events */
- PL_MapEvents(self, _pl_destroyEvent, NULL);
-
- if ( self->type == EventQueueIsNative )
- _pl_CleanupNativeNotifier(self);
-
- /* destroying the monitor also destroys the name */
- PR_ExitMonitor(self->monitor);
- PR_DestroyMonitor(self->monitor);
- PR_DELETE(self);
-
-}
-
-PR_IMPLEMENT(PRStatus)
-PL_PostEvent(PLEventQueue* self, PLEvent* event)
-{
- PRStatus err = PR_SUCCESS;
- PRMonitor* mon;
-
- if (self == NULL)
- return PR_FAILURE;
-
- mon = self->monitor;
- PR_EnterMonitor(mon);
-
- /* insert event into thread's event queue: */
- if (event != NULL) {
- PR_APPEND_LINK(&event->link, &self->queue);
- }
-
- /* notify even if event is NULL */
- if ( self->type == EventQueueIsNative )
- err = _pl_NativeNotify(self);
-
- /*
- * This may fall on deaf ears if we're really notifying the native
- * thread, and no one has called PL_WaitForEvent (or PL_EventLoop):
- */
- err = PR_Notify(mon);
- PR_ExitMonitor(mon);
- return err;
-}
-
-PR_IMPLEMENT(void*)
-PL_PostSynchronousEvent(PLEventQueue* self, PLEvent* event)
-{
- void* result;
-
- if (self == NULL)
- return NULL;
-
- PR_ASSERT(event != NULL);
- PR_CEnterMonitor(event);
-
- if (PR_CurrentThread() == self->handlerThread) {
- /* Handle the case where the thread requesting the event handling
- is also the thread that's supposed to do the handling. */
- result = event->handler(event);
- }
- else {
- int i, entryCount = PR_GetMonitorEntryCount(self->monitor);
-
- event->synchronousResult = (void*)PR_TRUE;
- PL_PostEvent(self, event);
- /* We need to temporarily give up our event queue monitor if
- we're holding it, otherwise, the thread we're going to wait
- for notification from won't be able to enter it to process
- the event. */
- if (entryCount) {
- for (i = 0; i < entryCount; i++)
- PR_ExitMonitor(self->monitor);
- }
- PR_CWait(event, PR_INTERVAL_NO_TIMEOUT); /* wait for event to be handled or destroyed */
- if (entryCount) {
- for (i = 0; i < entryCount; i++)
- PR_EnterMonitor(self->monitor);
- }
- result = event->synchronousResult;
- event->synchronousResult = NULL;
- }
-
- PR_CExitMonitor(event);
-
- /* For synchronous events, they're destroyed here on the caller's
- thread before the result is returned. See PL_HandleEvent. */
- PL_DestroyEvent(event);
-
- return result;
-}
-
-PR_IMPLEMENT(PLEvent*)
-PL_GetEvent(PLEventQueue* self)
-{
- PLEvent* event = NULL;
- PRStatus err = PR_SUCCESS;
-
- if (self == NULL)
- return NULL;
-
- PR_EnterMonitor(self->monitor);
-
- if (!PR_CLIST_IS_EMPTY(&self->queue)) {
- if ( self->type == EventQueueIsNative )
- err = _pl_AcknowledgeNativeNotify(self);
-
- if (err) goto done;
-
- /* then grab the event and return it: */
- event = PR_EVENT_PTR(self->queue.next);
- PR_REMOVE_AND_INIT_LINK(&event->link);
- }
-
- done:
- PR_ExitMonitor(self->monitor);
- return event;
-}
-
-PR_IMPLEMENT(PRBool)
-PL_EventAvailable(PLEventQueue* self)
-{
- PRBool result = PR_FALSE;
-
- if (self == NULL)
- return PR_FALSE;
-
- PR_EnterMonitor(self->monitor);
-
- if (!PR_CLIST_IS_EMPTY(&self->queue))
- result = PR_TRUE;
-
- PR_ExitMonitor(self->monitor);
- return result;
-}
-
-PR_IMPLEMENT(void)
-PL_MapEvents(PLEventQueue* self, PLEventFunProc fun, void* data)
-{
- PRCList* qp;
-
- if (self == NULL)
- return;
-
- PR_EnterMonitor(self->monitor);
- qp = self->queue.next;
- while (qp != &self->queue) {
- PLEvent* event = PR_EVENT_PTR(qp);
- qp = qp->next;
- (*fun)(event, data, self);
- }
- PR_ExitMonitor(self->monitor);
-}
-
-static void PR_CALLBACK
-_pl_DestroyEventForOwner(PLEvent* event, void* owner, PLEventQueue* queue)
-{
- PR_ASSERT(PR_GetMonitorEntryCount(queue->monitor) > 0);
- if (event->owner == owner) {
- PR_LOG(event_lm, PR_LOG_DEBUG,
- ("$$$ \tdestroying event %0x for owner %0x", event, owner));
- PL_DequeueEvent(event, queue);
- if (event->synchronousResult == (void*)PR_TRUE) {
- PR_CEnterMonitor(event);
- event->synchronousResult = NULL;
- PR_CNotify(event);
- PR_CExitMonitor(event);
- }
- else {
- PL_DestroyEvent(event);
- }
- }
- else {
- PR_LOG(event_lm, PR_LOG_DEBUG,
- ("$$$ \tskipping event %0x for owner %0x", event, owner));
- }
-}
-
-PR_IMPLEMENT(void)
-PL_RevokeEvents(PLEventQueue* self, void* owner)
-{
- if (self == NULL)
- return;
-
- PR_LOG(event_lm, PR_LOG_DEBUG,
- ("$$$ revoking events for owner %0x", owner));
-
- /*
- ** First we enter the monitor so that no one else can post any events
- ** to the queue:
- */
- PR_EnterMonitor(self->monitor);
- PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ owner %0x, entered monitor", owner));
-
- /*
- ** Discard any pending events for this owner:
- */
- PL_MapEvents(self, _pl_DestroyEventForOwner, owner);
-
-#ifdef DEBUG
- {
- PRCList* qp = self->queue.next;
- while (qp != &self->queue) {
- PLEvent* event = PR_EVENT_PTR(qp);
- qp = qp->next;
- PR_ASSERT(event->owner != owner);
- }
- }
-#endif /* DEBUG */
-
- PR_ExitMonitor(self->monitor);
-
- PR_LOG(event_lm, PR_LOG_DEBUG,
- ("$$$ revoking events for owner %0x", owner));
-}
-
-static PRInt32
-_pl_GetEventCount(PLEventQueue* self)
-{
- PRCList* node;
- PRInt32 count = 0;
-
- PR_EnterMonitor(self->monitor);
- node = PR_LIST_HEAD(&self->queue);
- while (node != &self->queue) {
- count++;
- node = PR_NEXT_LINK(node);
- }
- PR_ExitMonitor(self->monitor);
-
- return count;
-}
-
-PR_IMPLEMENT(void)
-PL_ProcessPendingEvents(PLEventQueue* self)
-{
- PRInt32 count;
-
- if (self == NULL)
- return;
-
- if (PR_FALSE != self->processingEvents) return;
-
- self->processingEvents = PR_TRUE;
-
- /* Only process the events that are already in the queue, and
- * not any new events that get added. Do this by counting the
- * number of events currently in the queue
- */
- count = _pl_GetEventCount(self);
- while (count-- > 0) {
- PLEvent* event = PL_GetEvent(self);
- if (event == NULL) break;
-
- PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ processing event"));
- PL_HandleEvent(event);
- PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ done processing event"));
- }
- self->processingEvents = PR_FALSE;
-}
-
-/*******************************************************************************
- * Event Operations
- ******************************************************************************/
-
-PR_IMPLEMENT(void)
-PL_InitEvent(PLEvent* self, void* owner,
- PLHandleEventProc handler,
- PLDestroyEventProc destructor)
-{
- PR_INIT_CLIST(&self->link);
- self->handler = handler;
- self->destructor = destructor;
- self->owner = owner;
- self->synchronousResult = NULL;
-}
-
-PR_IMPLEMENT(void*)
-PL_GetEventOwner(PLEvent* self)
-{
- return self->owner;
-}
-
-PR_IMPLEMENT(void)
-PL_HandleEvent(PLEvent* self)
-{
- void* result;
-
- if (self == NULL)
- return;
-
- /* This event better not be on an event queue anymore. */
- PR_ASSERT(PR_CLIST_IS_EMPTY(&self->link));
-
- result = (*self->handler)(self);
- if (NULL != self->synchronousResult) {
- PR_CEnterMonitor(self);
- self->synchronousResult = result;
- PR_CNotify(self); /* wake up the guy waiting for the result */
- PR_CExitMonitor(self);
- }
- else {
- /* For asynchronous events, they're destroyed by the event-handler
- thread. See PR_PostSynchronousEvent. */
- PL_DestroyEvent(self);
- }
-}
-
-PR_IMPLEMENT(void)
-PL_DestroyEvent(PLEvent* self)
-{
- if (self == NULL)
- return;
-
- /* This event better not be on an event queue anymore. */
- PR_ASSERT(PR_CLIST_IS_EMPTY(&self->link));
-
- (*self->destructor)(self);
-}
-
-PR_IMPLEMENT(void)
-PL_DequeueEvent(PLEvent* self, PLEventQueue* queue)
-{
-#ifdef XP_MAC
-#pragma unused (queue)
-#endif
- if (self == NULL)
- return;
-
- /* Only the owner is allowed to dequeue events because once the
- client has put it in the queue, they have no idea whether it's
- been processed and destroyed or not. */
-/* PR_ASSERT(queue->handlerThread == PR_CurrentThread());*/
-
- PR_EnterMonitor(queue->monitor);
-
- PR_ASSERT(!PR_CLIST_IS_EMPTY(&self->link));
- PR_REMOVE_AND_INIT_LINK(&self->link);
-
- PR_ExitMonitor(queue->monitor);
-}
-
-/*******************************************************************************
- * Pure Event Queues
- *
- * For when you're only processing PLEvents and there is no native
- * select, thread messages, or AppleEvents.
- ******************************************************************************/
-
-PR_IMPLEMENT(PLEvent*)
-PL_WaitForEvent(PLEventQueue* self)
-{
- PLEvent* event;
- PRMonitor* mon;
-
- if (self == NULL)
- return NULL;
-
- mon = self->monitor;
- PR_EnterMonitor(mon);
-
- while ((event = PL_GetEvent(self)) == NULL) {
- PRStatus err;
- PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ waiting for event"));
- err = PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
- if ((err == PR_FAILURE)
- && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break;
- }
-
- PR_ExitMonitor(mon);
- return event;
-}
-
-PR_IMPLEMENT(void)
-PL_EventLoop(PLEventQueue* self)
-{
- if (self == NULL)
- return;
-
- while (PR_TRUE) {
- PLEvent* event = PL_WaitForEvent(self);
- if (event == NULL) {
- /* This can only happen if the current thread is interrupted */
- return;
- }
-
- PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ processing event"));
- PL_HandleEvent(event);
- PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ done processing event"));
- }
-}
-
-/*******************************************************************************
- * Native Event Queues
- *
- * For when you need to call select, or WaitNextEvent, and yet also want
- * to handle PLEvents.
- ******************************************************************************/
-
-static PRStatus
-_pl_SetupNativeNotifier(PLEventQueue* self)
-{
-#if defined(XP_MAC)
-#pragma unused (self)
-#endif
-
-#if defined(VMS)
- {
- unsigned int status;
- status = LIB$GET_EF(&self->efn);
- if (!$VMS_STATUS_SUCCESS(status))
- return PR_FAILURE;
- PR_LOG(event_lm, PR_LOG_DEBUG,
- ("$$$ Allocated event flag %d", self->efn));
- return PR_SUCCESS;
- }
-#elif defined(XP_UNIX)
- int err;
- int flags;
-
- err = pipe(self->eventPipe);
- if (err != 0) {
- return PR_FAILURE;
- }
-
- /* make the pipe nonblocking */
- flags = fcntl(self->eventPipe[0], F_GETFL, 0);
- if (flags == -1) {
- goto failed;
- }
- err = fcntl(self->eventPipe[0], F_SETFL, flags | O_NONBLOCK);
- if (err == -1) {
- goto failed;
- }
- flags = fcntl(self->eventPipe[1], F_GETFL, 0);
- if (flags == -1) {
- goto failed;
- }
- err = fcntl(self->eventPipe[1], F_SETFL, flags | O_NONBLOCK);
- if (err == -1) {
- goto failed;
- }
- return PR_SUCCESS;
-
-failed:
- close(self->eventPipe[0]);
- close(self->eventPipe[1]);
- return PR_FAILURE;
-#elif defined(XP_BEOS)
- /* hook up to the nsToolkit queue, however the appshell
- * isn't necessairly started, so we might have to create
- * the queue ourselves
- */
- char portname[64];
- char semname[64];
- sprintf(portname, "event%lx", self->handlerThread);
- sprintf(semname, "sync%lx", self->handlerThread);
-
- if((self->eventport = find_port(portname)) < 0)
- {
- /* create port
- */
- self->eventport = create_port(100, portname);
-
- /* We don't use the sem, but it has to be there
- */
- create_sem(0, semname);
- }
-
- return PR_SUCCESS;
-#else
- return PR_SUCCESS;
-#endif
-}
-
-static void
-_pl_CleanupNativeNotifier(PLEventQueue* self)
-{
-#if defined(XP_MAC)
-#pragma unused (self)
-#endif
-
-#if defined(VMS)
- {
- unsigned int status;
- PR_LOG(event_lm, PR_LOG_DEBUG,
- ("$$$ Freeing event flag %d", self->efn));
- status = LIB$FREE_EF(&self->efn);
- }
-#elif defined(XP_UNIX)
- close(self->eventPipe[0]);
- close(self->eventPipe[1]);
-#endif
-}
-
-#if defined(_WIN32) || defined(WIN16)
-static PRStatus
-_pl_NativeNotify(PLEventQueue* self)
-{
- PostMessage( self->eventReceiverWindow, _pr_PostEventMsgId,
- (WPARAM)0, (LPARAM)self);
- return PR_SUCCESS;
-}/* --- end _pl_NativeNotify() --- */
-#endif
-
-#if defined(XP_OS2)
-static PRStatus
-_pl_NativeNotify(PLEventQueue* self)
-{
- BOOL rc = WinPostMsg( self->eventReceiverWindow, _pr_PostEventMsgId,
- 0, MPFROMP(self));
- return (rc == TRUE) ? PR_SUCCESS : PR_FAILURE;
-}/* --- end _pl_NativeNotify() --- */
-#endif /* XP_OS2 */
-
-#if defined(VMS)
-/* Just set the event flag */
-static PRStatus
-_pl_NativeNotify(PLEventQueue* self)
-{
- unsigned int status;
- PR_LOG(event_lm, PR_LOG_DEBUG,
- ("_pl_NativeNotify: self=%p notifyCount=%d efn=%d",
- self, self->notifyCount, self->efn));
- self->notifyCount++;
- status = SYS$SETEF(self->efn);
- if ($VMS_STATUS_SUCCESS(status))
- return PR_SUCCESS;
- else
- return PR_FAILURE;
-}/* --- end _pl_NativeNotify() --- */
-#elif defined(XP_UNIX)
-static PRStatus
-_pl_NativeNotify(PLEventQueue* self)
-{
-#define NOTIFY_TOKEN 0xFA
- PRInt32 count;
- unsigned char buf[] = { NOTIFY_TOKEN };
-
- PR_LOG(event_lm, PR_LOG_DEBUG,
- ("_pl_NativeNotify: self=%p notifyCount=%d",
- self, self->notifyCount));
- count = write(self->eventPipe[1], buf, 1);
- if (count == 1) {
- self->notifyCount++;
- return PR_SUCCESS;
- } else if ((count == -1) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
- return PR_SUCCESS;
- } else
- return PR_FAILURE;
-}/* --- end _pl_NativeNotify() --- */
-#endif /* XP_UNIX */
-
-#if defined(XP_BEOS)
-struct ThreadInterfaceData
-{
- void *data;
- int32 sync;
-};
-
-static PRStatus
-_pl_NativeNotify(PLEventQueue* self)
-{
- struct ThreadInterfaceData id;
- id.data = self;
- id.sync = false;
- write_port(self->eventport, 'natv', &id, sizeof(id));
-
- return PR_SUCCESS; /* Is this correct? */
-}
-#endif /* XP_BEOS */
-
-#if defined(XP_MAC)
-static PRStatus
-_pl_NativeNotify(PLEventQueue* self)
-{
-#pragma unused (self)
- return PR_SUCCESS; /* XXX can fail? */
-}
-#endif /* XP_MAC */
-
-static PRStatus
-_pl_AcknowledgeNativeNotify(PLEventQueue* self)
-{
-#if defined(VMS)
- PR_LOG(event_lm, PR_LOG_DEBUG,
- ("_pl_AcknowledgeNativeNotify: self=%p notifyCount=%d efn=%d",
- self, self->notifyCount, self->efn));
- /*
- ** If this is the last entry, then clear the event flag. Also make sure
- ** the flag is cleared on any spurious wakeups.
- */
- if (self->notifyCount <= 1)
- sys$clref(self->efn);
-
- if (self->notifyCount <= 0)
- return PR_SUCCESS;
-
- self->notifyCount--;
-
- return PR_SUCCESS;
-#elif defined(XP_UNIX)
-
- PRInt32 count;
- unsigned char c;
-
- PR_LOG(event_lm, PR_LOG_DEBUG,
- ("_pl_AcknowledgeNativeNotify: self=%p notifyCount=%d",
- self, self->notifyCount));
- if (self->notifyCount <= 0) return PR_SUCCESS;
- /* consume the byte NativeNotify put in our pipe: */
- count = read(self->eventPipe[0], &c, 1);
- if ((count == 1) && (c == NOTIFY_TOKEN)) {
- self->notifyCount--;
- return PR_SUCCESS;
- } else if ((count == -1) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
- return PR_SUCCESS;
- } else
- return PR_FAILURE;
-#else
-
-#if defined(XP_MAC)
-#pragma unused (self)
-#endif
-
- /* nothing to do on the other platforms */
- return PR_SUCCESS;
-#endif
-}
-
-PR_IMPLEMENT(PRInt32)
-PL_GetEventQueueSelectFD(PLEventQueue* self)
-{
- if (self == NULL)
- return -1;
-
-#if defined(VMS)
- return -(self->efn);
-#elif defined(XP_UNIX)
- return self->eventPipe[0];
-#else
- return -1; /* other platforms don't handle this (yet) */
-#endif
-}
-
-PR_IMPLEMENT(PRBool)
-PL_IsQueueOnCurrentThread( PLEventQueue *queue )
-{
- PRThread *me = PR_GetCurrentThread();
- if ( me == queue->handlerThread )
- return PR_TRUE;
- else
- return PR_FALSE;
-} /* end PL_IsQueueOnCurrentThread() */
-
-#if defined(WIN16) || defined(_WIN32)
-/*
-** Global Instance handle...
-** In Win32 this is the module handle of the DLL.
-**
-*/
-static HINSTANCE _pr_hInstance;
-#endif
-
-#if defined(WIN16)
-/*
-** Function LibMain() is required by Win16
-**
-*/
-int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg,
- WORD cbHeapSize, LPSTR lpszCmdLine )
-{
- _pr_hInstance = hInst;
- return TRUE;
-}
-#endif /* WIN16 */
-
-#if defined(_WIN32)
-
-/*
-** Initialization routine for the NSPR DLL...
-*/
-
-BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved)
-{
- switch (dwReason)
- {
- case DLL_PROCESS_ATTACH:
- _pr_hInstance = hDLL;
- break;
-
- case DLL_THREAD_ATTACH:
- break;
-
- case DLL_THREAD_DETACH:
- break;
-
- case DLL_PROCESS_DETACH:
- _pr_hInstance = NULL;
- break;
- }
-
- return TRUE;
-}
-#endif
-
-
-#if defined(WIN16) || defined(_WIN32) || defined(XP_OS2)
-#ifdef XP_OS2
-MRESULT EXPENTRY
-_md_EventReceiverProc(HWND hwnd, ULONG uMsg, MPARAM wParam, MPARAM lParam)
-#else
-LRESULT CALLBACK
-#if defined(WIN16)
-__loadds
-#endif
-_md_EventReceiverProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-#endif
-{
- if (_pr_PostEventMsgId == uMsg )
- {
- PREventQueue *queue = (PREventQueue *)lParam;
-
- PR_ProcessPendingEvents(queue);
-#ifdef XP_OS2
- return MRFROMLONG(TRUE);
-#else
- return TRUE;
-#endif
- }
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
-}
-
-
-static PRBool isInitialized;
-static PRCallOnceType once;
-static PRLock *initLock;
-
-/*
-** InitWinEventLib() -- Create the Windows initialization lock
-**
-*/
-static PRStatus InitEventLib( void )
-{
- PR_ASSERT( initLock == NULL );
-
- initLock = PR_NewLock();
- if ( NULL == initLock )
- return PR_FAILURE;
- else
- return PR_SUCCESS;
-} /* end InitWinEventLib() */
-
-#endif /* Win16, Win32, OS2 */
-
-#if defined(_WIN32) || defined(WIN16)
-/*
-** _md_CreateEventQueue() -- ModelDependent initializer
-*/
-static void _md_CreateEventQueue( PLEventQueue *eventQueue )
-{
- WNDCLASS wc;
-
- /*
- ** If this is the first call to PL_InitializeEventsLib(),
- ** make the call to InitWinEventLib() to create the initLock.
- **
- ** Then lock the initializer lock to insure that
- ** we have exclusive control over the initialization sequence.
- **
- */
-
-
- /* Register the windows message for NSPR Event notification */
- _pr_PostEventMsgId = RegisterWindowMessage("NSPR_PostEvent");
-
- /* Register the class for the event receiver window */
- if (!GetClassInfo(_pr_hInstance, _pr_eventWindowClass, &wc)) {
- wc.style = 0;
- wc.lpfnWndProc = _md_EventReceiverProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = _pr_hInstance;
- wc.hIcon = NULL;
- wc.hCursor = NULL;
- wc.hbrBackground = (HBRUSH) NULL;
- wc.lpszMenuName = (LPCSTR) NULL;
- wc.lpszClassName = _pr_eventWindowClass;
- RegisterClass(&wc);
- }
-
- /* Create the event receiver window */
- eventQueue->eventReceiverWindow = CreateWindow(_pr_eventWindowClass,
- "NSPR:EventReceiver",
- 0, 0, 0, 10, 10,
- NULL, NULL, _pr_hInstance,
- NULL);
- PR_ASSERT(eventQueue->eventReceiverWindow);
-
- return;
-} /* end _md_CreateEventQueue() */
-#endif /* Winxx */
-
-#if defined(XP_OS2)
-/*
-** _md_CreateEventQueue() -- ModelDependent initializer
-*/
-static void _md_CreateEventQueue( PLEventQueue *eventQueue )
-{
- /* Must have HMQ for this & can't assume we already have appshell */
- if( FALSE == WinQueryQueueInfo( HMQ_CURRENT, NULL, 0))
- {
- HAB hab = WinInitialize( 0);
- WinCreateMsgQueue( hab, 0);
- }
-
- if( !_pr_PostEventMsgId)
- {
- WinRegisterClass( 0 /* hab_current */,
- _pr_eventWindowClass,
- _md_EventReceiverProc,
- 0, 0);
-
- _pr_PostEventMsgId = WinAddAtom( WinQuerySystemAtomTable(),
- "NSPR_PostEvent");
- }
-
- eventQueue->eventReceiverWindow = WinCreateWindow( HWND_DESKTOP,
- _pr_eventWindowClass,
- "", 0,
- 0, 0, 0, 0,
- HWND_DESKTOP,
- HWND_TOP,
- 0,
- NULL,
- NULL);
- PR_ASSERT(eventQueue->eventReceiverWindow);
-
- return;
-} /* end _md_CreateEventQueue() */
-#endif /* XP_OS2 */
-
-#if defined(XP_UNIX) || defined(XP_MAC) || defined(XP_BEOS)
-/*
-** _md_CreateEventQueue() -- ModelDependent initializer
-*/
-static void _md_CreateEventQueue( PLEventQueue *eventQueue )
-{
-#ifdef XP_MAC
-#pragma unused(eventQueue)
-#endif
-
- /* there's really nothing special to do here,
- ** the guts of the unix stuff is in the setupnativenotify
- ** and related functions.
- */
- return;
-} /* end _md_CreateEventQueue() */
-#endif /* XP_UNIX */
-/* --- end plevent.c --- */
diff --git a/lib/ds/plevent.h b/lib/ds/plevent.h
deleted file mode 100644
index 38871055..00000000
--- a/lib/ds/plevent.h
+++ /dev/null
@@ -1,497 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*
- * The contents of this file are subject to the Netscape Public License
- * Version 1.1 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
-/**********************************************************************
-NSPL Events
-
-Defining Events
----------------
-
-Events are essentially structures that represent argument lists for a
-function that will run on another thread. All event structures you
-define must include a PLEvent struct as their first field:
-
- typedef struct MyEventType {
- PLEvent e;
- // arguments follow...
- int x;
- char* y;
- } MyEventType;
-
-It is also essential that you establish a model of ownership for each
-argument passed in an event record, i.e. whether particular arguments
-will be deleted by the event destruction callback, or whether they
-only loaned to the event handler callback, and guaranteed to persist
-until the time at which the handler is called.
-
-Sending Events
---------------
-
-Events are initialized by PL_InitEvent and can be sent via
-PL_PostEvent or PL_PostSynchronousEvent. Events can also have an
-owner. The owner of an event can revoke all the events in a given
-event-queue by calling PL_RevokeEvents. An owner might want
-to do this if, for instance, it is being destroyed, and handling the
-events after the owner's destruction would cause an error (e.g. an
-MWContext).
-
-Since the act of initializing and posting an event must be coordinated
-with it's possible revocation, it is essential that the event-queue's
-monitor be entered surrounding the code that constructs, initializes
-and posts the event:
-
- void postMyEvent(MyOwner* owner, int x, char* y)
- {
- MyEventType* event;
-
- PL_ENTER_EVENT_QUEUE_MONITOR(myQueue);
-
- // construct
- event = PR_NEW(MyEventType);
- if (event == NULL) goto done;
-
- // initialize
- PL_InitEvent(event, owner,
- (PLHandleEventProc)handleMyEvent,
- (PLDestroyEventProc)destroyMyEvent);
- event->x = x;
- event->y = strdup(y);
-
- // post
- PL_PostEvent(myQueue, &event->e);
-
- done:
- PL_EXIT_EVENT_QUEUE_MONITOR(myQueue);
- }
-
-If you don't call PL_InitEvent and PL_PostEvent within the
-event-queue's monitor, you'll get a big red assert.
-
-Handling Events
----------------
-
-To handle an event you must write a callback that is passed the event
-record you defined containing the event's arguments:
-
- void* handleMyEvent(MyEventType* event)
- {
- doit(event->x, event->y);
- return NULL; // you could return a value for a sync event
- }
-
-Similarly for the destruction callback:
-
- void destroyMyEvent(MyEventType* event)
- {
- free(event->y); // created by strdup
- free(event);
- }
-
-Processing Events in Your Event Loop
-------------------------------------
-
-If your main loop only processes events delivered to the event queue,
-things are rather simple. You just get the next event (which may
-block), and then handle it:
-
- while (1) {
- event = PL_GetEvent(myQueue);
- PL_HandleEvent(event);
- }
-
-However, if other things must be waited on, you'll need to obtain a
-file-descriptor that represents your event queue, and hand it to select:
-
- fd = PL_GetEventQueueSelectFD(myQueue);
- ...add fd to select set...
- while (select(...)) {
- if (...fd...) {
- PL_ProcessPendingEvents(myQueue);
- }
- ...
- }
-
-Of course, with Motif and Windows it's more complicated than that, and
-on Mac it's completely different, but you get the picture.
-
-Revoking Events
----------------
-If at any time an owner of events is about to be destroyed, you must
-take steps to ensure that no one tries to use the event queue after
-the owner is gone (or a crash may result). You can do this by either
-processing all the events in the queue before destroying the owner:
-
- {
- ...
- PL_ENTER_EVENT_QUEUE_MONITOR(myQueue);
- PL_ProcessPendingEvents(myQueue);
- DestroyMyOwner(owner);
- PL_EXIT_EVENT_QUEUE_MONITOR(myQueue);
- ...
- }
-
-or by revoking the events that are in the queue for that owner. This
-removes them from the queue and calls their destruction callback:
-
- {
- ...
- PL_ENTER_EVENT_QUEUE_MONITOR(myQueue);
- PL_RevokeEvents(myQueue, owner);
- DestroyMyOwner(owner);
- PL_EXIT_EVENT_QUEUE_MONITOR(myQueue);
- ...
- }
-
-In either case it is essential that you be in the event-queue's monitor
-to ensure that all events are removed from the queue for that owner,
-and to ensure that no more events will be delivered for that owner.
-**********************************************************************/
-
-#ifndef prevent_h___
-#define prevent_h___
-
-#include "prtypes.h"
-#include "prclist.h"
-#include "prthread.h"
-#include "prmon.h"
-
-/* For HWND */
-#if defined(_WIN32) && !defined(__MINGW32__)
-#include <windef.h>
-#elif defined(WIN16) || defined(__MINGW32__)
-#include <windows.h>
-#elif defined(XP_OS2)
-#define INCL_DOSPROCESS
-#include <os2.h>
-#endif
-
-PR_BEGIN_EXTERN_C
-
-/* Typedefs */
-
-typedef struct PLEvent PLEvent;
-typedef struct PLEventQueue PLEventQueue;
-
-/*******************************************************************************
- * Event Queue Operations
- ******************************************************************************/
-
-/*
-** Creates a new event queue. Returns NULL on failure.
-*/
-PR_EXTERN(PLEventQueue*)
-PL_CreateEventQueue(char* name, PRThread* handlerThread);
-
-
-/* -----------------------------------------------------------------------
-** FUNCTION: PL_CreateNativeEventQueue()
-**
-** DESCRIPTION:
-** PL_CreateNativeEventQueue() creates an event queue that
-** uses platform specific notify mechanisms.
-**
-** For Unix, the platform specific notify mechanism provides
-** an FD that may be extracted using the function
-** PL_GetEventQueueSelectFD(). The FD returned may be used in
-** a select() function call.
-**
-** For Windows, the platform specific notify mechanism
-** provides an event receiver window that is called by
-** Windows to process the event using the windows message
-** pump engine.
-**
-** INPUTS:
-** name: A name, as a diagnostic aid.
-**
-** handlerThread: A pointer to the PRThread structure for
-** the thread that will "handle" events posted to this event
-** queue.
-**
-** RETURNS:
-** A pointer to a PLEventQueue structure or NULL.
-**
-*/
-PR_EXTERN(PLEventQueue *)
- PL_CreateNativeEventQueue(
- char *name,
- PRThread *handlerThread
- );
-
-/* -----------------------------------------------------------------------
-** FUNCTION: PL_CreateMonitoredEventQueue()
-**
-** DESCRIPTION:
-** PL_CreateMonitoredEventQueue() creates an event queue. No
-** platform specific notify mechanism is created with the
-** event queue.
-**
-** Users of this type of event queue must explicitly poll the
-** event queue to retreive and process events.
-**
-**
-** INPUTS:
-** name: A name, as a diagnostic aid.
-**
-** handlerThread: A pointer to the PRThread structure for
-** the thread that will "handle" events posted to this event
-** queue.
-**
-** RETURNS:
-** A pointer to a PLEventQueue structure or NULL.
-**
-*/
-PR_EXTERN(PLEventQueue *)
- PL_CreateMonitoredEventQueue(
- char *name,
- PRThread *handlerThread
- );
-
-/*
-** Destroys an event queue.
-*/
-PR_EXTERN(void)
-PL_DestroyEventQueue(PLEventQueue* self);
-
-/*
-** Returns the monitor associated with an event queue. This monitor is
-** selectable. The monitor should be entered to protect against anyone
-** calling PL_RevokeEvents while the event is trying to be constructed
-** and delivered.
-*/
-PR_EXTERN(PRMonitor*)
-PL_GetEventQueueMonitor(PLEventQueue* self);
-
-#define PL_ENTER_EVENT_QUEUE_MONITOR(queue) \
- PR_EnterMonitor(PL_GetEventQueueMonitor(queue))
-
-#define PL_EXIT_EVENT_QUEUE_MONITOR(queue) \
- PR_ExitMonitor(PL_GetEventQueueMonitor(queue))
-
-/*
-** Posts an event to an event queue, waking up any threads waiting for an
-** event. If event is NULL, notification still occurs, but no event will
-** be available.
-**
-** Any events delivered by this routine will be destroyed by PL_HandleEvent
-** when it is called (by the event-handling thread).
-*/
-PR_EXTERN(PRStatus)
-PL_PostEvent(PLEventQueue* self, PLEvent* event);
-
-/*
-** Like PL_PostEvent, this routine posts an event to the event handling
-** thread, but does so synchronously, waiting for the result. The result
-** which is the value of the handler routine is returned.
-**
-** Any events delivered by this routine will be not be destroyed by
-** PL_HandleEvent, but instead will be destroyed just before the result is
-** returned (by the current thread).
-*/
-PR_EXTERN(void*)
-PL_PostSynchronousEvent(PLEventQueue* self, PLEvent* event);
-
-/*
-** Gets an event from an event queue. Returns NULL if no event is
-** available.
-*/
-PR_EXTERN(PLEvent*)
-PL_GetEvent(PLEventQueue* self);
-
-/*
-** Returns true if there is an event available for PL_GetEvent.
-*/
-PR_EXTERN(PRBool)
-PL_EventAvailable(PLEventQueue* self);
-
-/*
-** This is the type of the function that must be passed to PL_MapEvents
-** (see description below).
-*/
-typedef void
-(PR_CALLBACK *PLEventFunProc)(PLEvent* event, void* data, PLEventQueue* queue);
-
-/*
-** Applies a function to every event in the event queue. This can be used
-** to selectively handle, filter, or remove events. The data pointer is
-** passed to each invocation of the function fun.
-*/
-PR_EXTERN(void)
-PL_MapEvents(PLEventQueue* self, PLEventFunProc fun, void* data);
-
-/*
-** This routine walks an event queue and destroys any event whose owner is
-** the owner specified. The == operation is used to compare owners.
-*/
-PR_EXTERN(void)
-PL_RevokeEvents(PLEventQueue* self, void* owner);
-
-/*
-** This routine processes all pending events in the event queue. It can be
-** called from the thread's main event-processing loop whenever the event
-** queue's selectFD is ready (returned by PL_GetEventQueueSelectFD).
-*/
-PR_EXTERN(void)
-PL_ProcessPendingEvents(PLEventQueue* self);
-
-/*******************************************************************************
- * Pure Event Queues
- *
- * For when you're only processing PLEvents and there is no native
- * select, thread messages, or AppleEvents.
- ******************************************************************************/
-
-/*
-** Blocks until an event can be returned from the event queue. This routine
-** may return NULL if the current thread is interrupted.
-*/
-PR_EXTERN(PLEvent*)
-PL_WaitForEvent(PLEventQueue* self);
-
-/*
-** One stop shopping if all you're going to do is process PLEvents. Just
-** call this and it loops forever processing events as they arrive. It will
-** terminate when your thread is interrupted or dies.
-*/
-PR_EXTERN(void)
-PL_EventLoop(PLEventQueue* self);
-
-/*******************************************************************************
- * Native Event Queues
- *
- * For when you need to call select, or WaitNextEvent, and yet also want
- * to handle PLEvents.
- ******************************************************************************/
-
-/*
-** This routine allows you to grab the file descriptor associated with an
-** event queue and use it in the readFD set of select. Useful for platforms
-** that support select, and must wait on other things besides just PLEvents.
-*/
-PR_EXTERN(PRInt32)
-PL_GetEventQueueSelectFD(PLEventQueue* self);
-
-/*
-** This routine will allow you to check to see if the given eventQueue in
-** on the current thread. It will return PR_TRUE if so, else it will return
-** PR_FALSE
-*/
-PR_EXTERN(PRBool)
- PL_IsQueueOnCurrentThread( PLEventQueue *queue );
-
-/*******************************************************************************
- * Event Operations
- ******************************************************************************/
-
-/*
-** The type of an event handler function. This function is passed as an
-** initialization argument to PL_InitEvent, and called by
-** PL_HandleEvent. If the event is called synchronously, a void* result
-** may be returned (otherwise any result will be ignored).
-*/
-typedef void*
-(PR_CALLBACK *PLHandleEventProc)(PLEvent* self);
-
-/*
-** The type of an event destructor function. This function is passed as
-** an initialization argument to PL_InitEvent, and called by
-** PL_DestroyEvent.
-*/
-typedef void
-(PR_CALLBACK *PLDestroyEventProc)(PLEvent* self);
-
-/*
-** Initializes an event. Usually events are embedded in a larger event
-** structure which holds event-specific data, so this is an initializer
-** for that embedded part of the structure.
-*/
-PR_EXTERN(void)
-PL_InitEvent(PLEvent* self, void* owner,
- PLHandleEventProc handler,
- PLDestroyEventProc destructor);
-
-/*
-** Returns the owner of an event.
-*/
-PR_EXTERN(void*)
-PL_GetEventOwner(PLEvent* self);
-
-/*
-** Handles an event, calling the event's handler routine.
-*/
-PR_EXTERN(void)
-PL_HandleEvent(PLEvent* self);
-
-/*
-** Destroys an event, calling the event's destructor.
-*/
-PR_EXTERN(void)
-PL_DestroyEvent(PLEvent* self);
-
-/*
-** Removes an event from an event queue.
-*/
-PR_EXTERN(void)
-PL_DequeueEvent(PLEvent* self, PLEventQueue* queue);
-
-/*******************************************************************************
- * Private Stuff
- ******************************************************************************/
-
-struct PLEvent {
- PRCList link;
- PLHandleEventProc handler;
- PLDestroyEventProc destructor;
- void* owner;
- void* synchronousResult;
- /* other fields follow... */
-};
-
-/******************************************************************************/
-
-/*
-** Returns the event queue associated with the main thread.
-**
-*/
-#ifdef XP_PC
-/* -----------------------------------------------------------------------
-** FUNCTION: PL_GetNativeEventReceiverWindow()
-**
-** DESCRIPTION:
-** PL_GetNativeEventReceiverWindow() returns the windows
-** handle of the event receiver window associated with the
-** referenced PLEventQueue argument.
-**
-** INPUTS:
-** PLEventQueue pointer
-**
-** RETURNS:
-** event receiver window handle.
-**
-** RESTRICTIONS: MS-Windows ONLY.
-**
-*/
-PR_EXTERN(HWND)
- PL_GetNativeEventReceiverWindow(
- PLEventQueue *eqp
- );
-
-#endif /* XP_PC */
-
-PR_END_EXTERN_C
-
-#endif /* prevent_h___ */
diff --git a/lib/ds/plvrsion.c b/lib/ds/plvrsion.c
index ac88e344..009ed53a 100644
--- a/lib/ds/plvrsion.c
+++ b/lib/ds/plvrsion.c
@@ -42,7 +42,14 @@
#define _DEBUG_STRING ""
#endif
-PRVersionDescription prVersionDescription_libplds3 =
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplds, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
{
/* version */ 2, /* this is the only one supported */
/* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */
@@ -92,7 +99,7 @@ PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
dummy = rcsid;
dummy = sccsid;
#endif
- return &prVersionDescription_libplds3;
+ return &VERSION_DESC_NAME;
} /* versionEntryPointType */
/* plvrsion.c */
diff --git a/lib/libc/src/plc.rc b/lib/libc/src/plc.rc
index 3283a44b..30287525 100644
--- a/lib/libc/src/plc.rc
+++ b/lib/libc/src/plc.rc
@@ -22,6 +22,10 @@
#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
@@ -66,7 +70,7 @@ BEGIN
VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
VALUE "FileVersion", PR_VERSION "\0"
VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "LegalCopyright", "Copyright \251 1996-1999 Netscape Communications Corporation\0"
+ VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
VALUE "ProductName", "Netscape Portable Runtime\0"
VALUE "ProductVersion", PR_VERSION "\0"
diff --git a/lib/libc/src/plvrsion.c b/lib/libc/src/plvrsion.c
index 619fc4bb..93c08c77 100644
--- a/lib/libc/src/plvrsion.c
+++ b/lib/libc/src/plvrsion.c
@@ -42,7 +42,14 @@
#define _DEBUG_STRING ""
#endif
-PRVersionDescription prVersionDescription_libplc3 =
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplc, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
{
/* version */ 2, /* this is the only one supported */
/* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */
@@ -92,7 +99,7 @@ PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
dummy = rcsid;
dummy = sccsid;
#endif
- return &prVersionDescription_libplc3;
+ return &VERSION_DESC_NAME;
} /* versionEntryPointType */
/* plvrsion.c */
diff --git a/lib/prstreams/plvrsion.c b/lib/prstreams/plvrsion.c
index 55251da2..47b0311e 100644
--- a/lib/prstreams/plvrsion.c
+++ b/lib/prstreams/plvrsion.c
@@ -42,7 +42,14 @@
#define _DEBUG_STRING ""
#endif
-PRVersionDescription prVersionDescription_libprstrms3 =
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libprstrms, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
{
/* version */ 2, /* this is the only one supported */
/* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */
@@ -92,7 +99,7 @@ PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
dummy = rcsid;
dummy = sccsid;
#endif
- return &prVersionDescription_libprstrms3;
+ return &VERSION_DESC_NAME;
} /* versionEntryPointType */
/* plvrsion.c */
diff --git a/lib/prstreams/prstrms.cpp b/lib/prstreams/prstrms.cpp
index 09ecc26c..0fb34f79 100644
--- a/lib/prstreams/prstrms.cpp
+++ b/lib/prstreams/prstrms.cpp
@@ -222,7 +222,7 @@ PRfilebuf::underflow()
}
streambuf*
-PRfilebuf::setbuf(char *buffptr, int bufflen)
+PRfilebuf::setbuf(char *buffptr, PRstreambuflen bufflen)
{
if (is_open() && (ebuf()))
return 0;
diff --git a/lib/prstreams/prstrms.h b/lib/prstreams/prstrms.h
index 2af53953..43ce7fed 100644
--- a/lib/prstreams/prstrms.h
+++ b/lib/prstreams/prstrms.h
@@ -31,6 +31,12 @@
#endif
#include <iostream.h>
+#if defined(AIX) && defined(__64BIT__)
+typedef long PRstreambuflen;
+#else
+typedef int PRstreambuflen;
+#endif
+
#if defined (PRFSTREAMS_BROKEN)
// fix it sometime
@@ -51,7 +57,7 @@ public:
~PRfilebuf();
virtual int overflow(int=EOF);
virtual int underflow();
- virtual streambuf *setbuf(char *buff, int bufflen);
+ virtual streambuf *setbuf(char *buff, PRstreambuflen bufflen);
virtual streampos seekoff(streamoff, ios::seek_dir, int);
virtual int sync();
PRfilebuf *open(const char *name, int mode, int flags);
diff --git a/lib/prstreams/prstrms.rc b/lib/prstreams/prstrms.rc
index 6fecf644..4938cc7d 100644
--- a/lib/prstreams/prstrms.rc
+++ b/lib/prstreams/prstrms.rc
@@ -22,6 +22,10 @@
#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
@@ -66,7 +70,7 @@ BEGIN
VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
VALUE "FileVersion", PR_VERSION "\0"
VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "LegalCopyright", "Copyright \251 1996-1999 Netscape Communications Corporation\0"
+ VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
VALUE "ProductName", "Netscape Portable Runtime\0"
VALUE "ProductVersion", PR_VERSION "\0"
diff --git a/macbuild/NSPR20PPC.mcp b/macbuild/NSPR20PPC.mcp
index 2a9db190..fa75d4da 100644
--- a/macbuild/NSPR20PPC.mcp
+++ b/macbuild/NSPR20PPC.mcp
Binary files differ
diff --git a/makefile.win b/makefile.win
index 6c45879f..5948366b 100644
--- a/makefile.win
+++ b/makefile.win
@@ -82,7 +82,7 @@ PR_OBJDIR = WIN954.0_OPT.OBJ
all:: export libs install
-export libs install clobber clobber_all clean::
+export libs install clobber clobber_all clean depend::
!if "$(MOZ_BITS)" == "16"
set PATH=%WATCPATH%
set INCLUDE=%WATC_INC%
@@ -103,6 +103,3 @@ export::
$(MAKE_INSTALL) $(XPDIST)\$(PR_OBJDIR)\lib\*.lib $(DIST)\lib
$(MAKE_INSTALL) $(XPDIST)\$(PR_OBJDIR)\lib\*.dll $(DIST)\bin
!endif
-
-depend::
- @echo NSPR20 has no dependencies. Skipped.
diff --git a/pr/include/MANIFEST b/pr/include/MANIFEST
index c8cb34f5..634968ef 100644
--- a/pr/include/MANIFEST
+++ b/pr/include/MANIFEST
@@ -37,13 +37,12 @@ prshma.h
prsystem.h
prthread.h
prtime.h
+prtpool.h
prtrace.h
prtypes.h
prvrsion.h
prwin16.h
-prlink_mac.h
-
obsolete/protypes.h
obsolete/prsem.h
obsolete/probslet.h
diff --git a/pr/include/md/_aix.h b/pr/include/md/_aix.h
index a80ccb06..58f37d39 100644
--- a/pr/include/md/_aix.h
+++ b/pr/include/md/_aix.h
@@ -59,6 +59,7 @@
#endif
#define _PR_HAVE_SYSV_SEMAPHORES
#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+#define _PR_ACCEPT_INHERIT_NONBLOCK
/* Timer operations */
#if defined(AIX_TIMERS)
diff --git a/pr/include/md/_aix32.cfg b/pr/include/md/_aix32.cfg
index c1267e23..2fca5190 100644
--- a/pr/include/md/_aix32.cfg
+++ b/pr/include/md/_aix32.cfg
@@ -73,6 +73,8 @@
#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
diff --git a/pr/include/md/_aix32in6.cfg b/pr/include/md/_aix32in6.cfg
index bc9458c6..0385e86a 100644
--- a/pr/include/md/_aix32in6.cfg
+++ b/pr/include/md/_aix32in6.cfg
@@ -76,6 +76,7 @@
#ifndef _PR_INET6
#define _PR_INET6
#endif
+#define PR_AF_INET6 24 /* same as AF_INET6 */
#ifndef NO_NSPR_10_SUPPORT
diff --git a/pr/include/md/_aix64.cfg b/pr/include/md/_aix64.cfg
index b8e3e884..59bb1a79 100644
--- a/pr/include/md/_aix64.cfg
+++ b/pr/include/md/_aix64.cfg
@@ -77,6 +77,7 @@
#ifndef _PR_INET6
#define _PR_INET6
#endif
+#define PR_AF_INET6 24 /* same as AF_INET6 */
#ifndef NO_NSPR_10_SUPPORT
diff --git a/pr/include/md/_beos.h b/pr/include/md/_beos.h
index e98e8f36..8b56dec3 100644
--- a/pr/include/md/_beos.h
+++ b/pr/include/md/_beos.h
@@ -285,6 +285,7 @@ struct protoent* getprotobynumber(int number);
#define _MD_CLOSE_DIR _MD_close_dir
#define _MD_MAKE_NONBLOCK _MD_make_nonblock
#define _MD_OPEN _MD_open
+#define _MD_OPEN_FILE _MD_open
#define _MD_CLOSE_FILE _MD_close_file
#define _MD_READ _MD_read
#define _MD_WRITE _MD_write
@@ -301,6 +302,7 @@ struct protoent* getprotobynumber(int number);
#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
diff --git a/pr/include/md/_hpux.h b/pr/include/md/_hpux.h
index 0d45f6c3..22c38c44 100644
--- a/pr/include/md/_hpux.h
+++ b/pr/include/md/_hpux.h
@@ -48,6 +48,7 @@
#define _PR_STAT_HAS_ONLY_ST_ATIME
#define _PR_HAVE_POSIX_SEMAPHORES
#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#define _PR_ACCEPT_INHERIT_NONBLOCK
#undef _PR_HAVE_ATOMIC_OPS
diff --git a/pr/include/md/_hpux32.cfg b/pr/include/md/_hpux32.cfg
index 1afc14a4..85ff9476 100644
--- a/pr/include/md/_hpux32.cfg
+++ b/pr/include/md/_hpux32.cfg
@@ -30,6 +30,8 @@
#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
diff --git a/pr/include/md/_hpux64.cfg b/pr/include/md/_hpux64.cfg
index d2b626e2..3450f7fa 100644
--- a/pr/include/md/_hpux64.cfg
+++ b/pr/include/md/_hpux64.cfg
@@ -31,6 +31,8 @@
#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
diff --git a/pr/include/md/_irix.h b/pr/include/md/_irix.h
index f5f20eb2..dea7f654 100644
--- a/pr/include/md/_irix.h
+++ b/pr/include/md/_irix.h
@@ -60,6 +60,7 @@
#define HAVE_POINTER_LOCALTIME_R
#define _PR_HAVE_POSIX_SEMAPHORES
#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#define _PR_ACCEPT_INHERIT_NONBLOCK
/* Initialization entry points */
NSPR_API(void) _MD_EarlyInit(void);
diff --git a/pr/include/md/_irix32.cfg b/pr/include/md/_irix32.cfg
index f791faf8..ee6fc686 100644
--- a/pr/include/md/_irix32.cfg
+++ b/pr/include/md/_irix32.cfg
@@ -34,6 +34,8 @@
#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
diff --git a/pr/include/md/_irix64.cfg b/pr/include/md/_irix64.cfg
index 7e988172..ddc4305c 100644
--- a/pr/include/md/_irix64.cfg
+++ b/pr/include/md/_irix64.cfg
@@ -35,6 +35,8 @@
#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
diff --git a/pr/include/md/_linux.cfg b/pr/include/md/_linux.cfg
index aa99901c..33fa2683 100644
--- a/pr/include/md/_linux.cfg
+++ b/pr/include/md/_linux.cfg
@@ -27,6 +27,8 @@
#define LINUX
#endif
+#define PR_AF_INET6 10 /* same as AF_INET6 */
+
#ifdef __powerpc__
#undef IS_LITTLE_ENDIAN
diff --git a/pr/include/md/_linux.h b/pr/include/md/_linux.h
index 7980934c..11885b41 100644
--- a/pr/include/md/_linux.h
+++ b/pr/include/md/_linux.h
@@ -70,6 +70,10 @@
#else
#define _PR_NO_LARGE_FILES
#endif
+#ifdef _PR_INET6
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_INET6_PROBE
+#endif
#define _PR_HAVE_SYSV_SEMAPHORES
#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
diff --git a/pr/include/md/_macos.h b/pr/include/md/_macos.h
index e6ecd016..cf38977f 100644
--- a/pr/include/md/_macos.h
+++ b/pr/include/md/_macos.h
@@ -318,6 +318,7 @@ typedef enum IOOperation {
#define _MD_INIT_IO()
#define _MD_OPEN _MD_Open
+#define _MD_OPEN_FILE _MD_Open
#define _MD_CLOSE_FILE FSClose
#define _MD_READ(fd,buf,amount) ReadWriteProc(fd,buf,amount,READ_ASYNC)
#define _MD_WRITE(fd,buf,amount) ReadWriteProc(fd,buf,amount,WRITE_ASYNC)
@@ -368,6 +369,7 @@ extern char* _MD_ReadDir(struct _MDDir *md,PRIntn flags);
#define _MD_CLOSE_DIR _MD_CloseDir
#define _MD_MKDIR _MD_MkDir
+#define _MD_MAKE_DIR _MD_MkDir
#define _MD_RMDIR _MD_Delete
/*
diff --git a/pr/include/md/_os2.h b/pr/include/md/_os2.h
index 9fb935c2..70e8d112 100644
--- a/pr/include/md/_os2.h
+++ b/pr/include/md/_os2.h
@@ -182,6 +182,7 @@ struct _MDProcess {
/* --- 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)
@@ -198,6 +199,7 @@ extern PRInt32 _MD_CloseFile(PRInt32 osfd);
#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)
diff --git a/pr/include/md/_osf1.cfg b/pr/include/md/_osf1.cfg
index 576af82b..e01e9df5 100644
--- a/pr/include/md/_osf1.cfg
+++ b/pr/include/md/_osf1.cfg
@@ -36,6 +36,8 @@
#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
diff --git a/pr/include/md/_osf1.h b/pr/include/md/_osf1.h
index 96a2fe22..c0b95cb5 100644
--- a/pr/include/md/_osf1.h
+++ b/pr/include/md/_osf1.h
@@ -46,9 +46,14 @@
#define _PR_USE_POLL
#define _PR_STAT_HAS_ONLY_ST_ATIME
#define _PR_HAVE_LARGE_OFF_T
-#ifdef _PR_INET6
#define _PR_HAVE_GETIPNODEBYNAME
#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_INET6_PROBE
+#ifndef _PR_INET6
+#define AF_INET6 26
+#define AI_V4MAPPED 0x00000010
+#define AI_ALL 0x00000008
+#define AI_ADDRCONFIG 0x00000020
#endif
#define _PR_HAVE_POSIX_SEMAPHORES
#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
diff --git a/pr/include/md/_solaris.h b/pr/include/md/_solaris.h
index 535c520e..081636e0 100644
--- a/pr/include/md/_solaris.h
+++ b/pr/include/md/_solaris.h
@@ -73,6 +73,15 @@
#define _PR_HAVE_POSIX_SEMAPHORES
#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
#define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_INET6_PROBE
+#define _PR_ACCEPT_INHERIT_NONBLOCK
+#ifndef _PR_INET6
+#define AF_INET6 26
+#define AI_V4MAPPED 0x0001
+#define AI_ALL 0x0002
+#define AI_ADDRCONFIG 0x0004
+#endif
#include "prinrval.h"
NSPR_API(PRIntervalTime) _MD_Solaris_GetInterval(void);
diff --git a/pr/include/md/_solaris32.cfg b/pr/include/md/_solaris32.cfg
index f6b988a1..e4c9a9fe 100644
--- a/pr/include/md/_solaris32.cfg
+++ b/pr/include/md/_solaris32.cfg
@@ -41,6 +41,8 @@
#error unknown processor
#endif
+#define PR_AF_INET6 26 /* same as AF_INET6 */
+
#define PR_BYTES_PER_BYTE 1
#define PR_BYTES_PER_SHORT 2
#define PR_BYTES_PER_INT 4
diff --git a/pr/include/md/_solaris64.cfg b/pr/include/md/_solaris64.cfg
index 40832724..b302961b 100644
--- a/pr/include/md/_solaris64.cfg
+++ b/pr/include/md/_solaris64.cfg
@@ -42,6 +42,8 @@
#endif
#define IS_64
+#define PR_AF_INET6 26 /* same as AF_INET6 */
+
#define PR_BYTES_PER_BYTE 1
#define PR_BYTES_PER_SHORT 2
#define PR_BYTES_PER_INT 4
diff --git a/pr/include/md/_unixos.h b/pr/include/md/_unixos.h
index e44ab7b8..7bd86872 100644
--- a/pr/include/md/_unixos.h
+++ b/pr/include/md/_unixos.h
@@ -334,7 +334,8 @@ extern PRStatus _MD_UnlockFile(PRInt32 osfd);
#define _MD_OPEN_DIR(dir, name) _MD_open_dir(dir, name)
#define _MD_CLOSE_DIR(dir) _MD_close_dir(dir)
#define _MD_READ_DIR(dir, flags) _MD_read_dir(dir, flags)
-#define _MD_OPEN(name, osflags, mode ) _MD_open(name, osflags, mode)
+#define _MD_OPEN(name, osflags, mode) _MD_open(name, osflags, mode)
+#define _MD_OPEN_FILE(name, osflags, mode) _MD_open(name, osflags, mode)
extern PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount);
#define _MD_READ(fd,buf,amount) _MD_read(fd,buf,amount)
extern PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount);
@@ -347,6 +348,7 @@ extern PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount);
#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)
diff --git a/pr/include/md/_unixware7.cfg b/pr/include/md/_unixware7.cfg
index 3e50f662..855500c1 100644
--- a/pr/include/md/_unixware7.cfg
+++ b/pr/include/md/_unixware7.cfg
@@ -33,6 +33,8 @@
#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
diff --git a/pr/include/md/_win95.cfg b/pr/include/md/_win95.cfg
index af9e0d11..318422f1 100644
--- a/pr/include/md/_win95.cfg
+++ b/pr/include/md/_win95.cfg
@@ -31,6 +31,8 @@
#define WIN95
#endif
+#define PR_AF_INET6 23 /* same as AF_INET6 */
+
#if defined(_M_IX86) || defined(_X86_)
#define IS_LITTLE_ENDIAN 1
diff --git a/pr/include/md/_win95.h b/pr/include/md/_win95.h
index 6878b152..4e8e37a7 100644
--- a/pr/include/md/_win95.h
+++ b/pr/include/md/_win95.h
@@ -158,9 +158,23 @@ struct _MDProcess {
/* --- 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
@@ -177,6 +191,7 @@ extern PRInt32 _MD_CloseFile(PRInt32 osfd);
#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
diff --git a/pr/include/md/_winnt.cfg b/pr/include/md/_winnt.cfg
index e3348445..76147e01 100644
--- a/pr/include/md/_winnt.cfg
+++ b/pr/include/md/_winnt.cfg
@@ -31,6 +31,8 @@
#define WINNT
#endif
+#define PR_AF_INET6 23 /* same as AF_INET6 */
+
#if defined(_M_IX86) || defined(_X86_)
#define IS_LITTLE_ENDIAN 1
diff --git a/pr/include/md/_winnt.h b/pr/include/md/_winnt.h
index 85ddd505..49756c2e 100644
--- a/pr/include/md/_winnt.h
+++ b/pr/include/md/_winnt.h
@@ -200,12 +200,26 @@ struct _MDProcess {
/* --- Misc stuff --- */
#define _MD_GET_SP(thread) (thread)->md.gcContext[6]
+/* --- NT security stuff --- */
+
+extern void _PR_NT_InitSids(void);
+extern void _PR_NT_FreeSids(void);
+extern PRStatus _PR_NT_MakeSecurityDescriptorACL(
+ PRIntn mode,
+ DWORD accessTable[],
+ PSECURITY_DESCRIPTOR *resultSD,
+ PACL *resultACL
+);
+extern void _PR_NT_FreeSecurityDescriptorACL(
+ PSECURITY_DESCRIPTOR pSD, PACL pACL);
+
/* --- IO stuff --- */
extern PRInt32 _md_Associate(HANDLE);
extern PRInt32 _PR_MD_CLOSE(PRInt32 osfd, PRBool socket);
#define _MD_OPEN _PR_MD_OPEN
+#define _MD_OPEN_FILE _PR_MD_OPEN_FILE
#define _MD_READ _PR_MD_READ
#define _MD_WRITE _PR_MD_WRITE
#define _MD_WRITEV _PR_MD_WRITEV
@@ -221,6 +235,7 @@ extern PRInt32 _PR_MD_CLOSE(PRInt32 osfd, PRBool socket);
#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
diff --git a/pr/include/nspr.h b/pr/include/nspr.h
index 45bec0b3..1936b5c4 100644
--- a/pr/include/nspr.h
+++ b/pr/include/nspr.h
@@ -49,6 +49,8 @@
#include "prsystem.h"
#include "prthread.h"
#include "prtime.h"
+#include "prtpool.h"
+#include "prtrace.h"
#include "prtypes.h"
#endif /* nspr_h___ */
diff --git a/pr/include/obsolete/probslet.h b/pr/include/obsolete/probslet.h
index 91efa45a..f62cb8d8 100644
--- a/pr/include/obsolete/probslet.h
+++ b/pr/include/obsolete/probslet.h
@@ -34,17 +34,6 @@ PR_BEGIN_EXTERN_C
*/
NSPR_API(PRStatus) PR_Yield(void);
-/*
-** These are obsolete and are replaced by PR_GetSocketOption() and
-** PR_SetSocketOption().
-*/
-
-NSPR_API(PRStatus) PR_GetSockOpt(
- PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen);
-
-NSPR_API(PRStatus) PR_SetSockOpt(
- PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen);
-
/************************************************************************/
/************* The following definitions are for select *****************/
/************************************************************************/
@@ -160,64 +149,6 @@ NSPR_API(PRInt32) PR_FD_NISSET(PRInt32 osfd, PR_fd_set *set);
NSPR_API(PRInt32) PR_Stat(const char *path, struct stat *buf);
#endif /* NO_NSPR_10_SUPPORT */
-/***********************************************************************
-** FUNCTION: PR_CreateNetAddr(), PR_DestroyNetAddr()
-** DESCRIPTION:
-** Create an instance of a PRNetAddr, assigning well known values as
-** appropriate.
-**
-** INPUTS
-** PRNetAddrValue val The value to be assigned to the IP Address portion
-** of the network address. This can only specify the
-** special well known values that are equivalent to
-** INADDR_ANY and INADDR_LOOPBACK.
-**
-** PRUInt16 port The port number to be assigned in the structure.
-**
-** OUTPUTS:
-** None
-**
-** RETURN:
-** PRNetAddr *addr The initialized address that has been allocated
-** from the heap. It must be freed by the caller.
-** A returned value of zero indicates an error. The
-** cause of the error (most likely low memory) may
-** be retrieved by calling PR_GetError().
-**
-***********************************************************************/
-NSPR_API(PRNetAddr*) PR_CreateNetAddr(PRNetAddrValue val, PRUint16 port);
-NSPR_API(PRStatus) PR_DestroyNetAddr(PRNetAddr *addr);
-
-
-
-/***********************************************************************
-** FUNCTION: PR_GetHostName() **OBSOLETE**
-** Use PR_GetSystemInfo() (prsystem.h) with an argument of
-** PR_SI_HOSTNAME instead.
-** DESCRIPTION:
-** Get the DNS name of the hosting computer.
-**
-** INPUTS:
-** char *name The location where the host's name is stored.
-** PRIntn bufsize Number of bytes in 'name'.
-** OUTPUTS:
-** PRHostEnt *name
-** This string is filled in by the runtime if the
-** function returns PR_SUCCESS. The string must be
-** allocated by the caller
-** RETURN:
-** PRStatus PR_SUCCESS if the succeeds. If it fails the
-** result will be PR_FAILURE and the reason for
-** the failure can be retrieved by PR_GetError().
-***********************************************************************/
-NSPR_API(PRStatus) PR_GetHostName(char *name, PRUint32 namelen);
-
-/*
-** Return the current thread's last error string.
-** obsoleted by PR_GetErrorText().
-*/
-NSPR_API(const char *) PR_GetErrorString(void);
-
PR_END_EXTERN_C
#endif /* defined(PROBSLET_H) */
diff --git a/pr/include/obsolete/protypes.h b/pr/include/obsolete/protypes.h
index 9cc57dfb..631137e4 100644
--- a/pr/include/obsolete/protypes.h
+++ b/pr/include/obsolete/protypes.h
@@ -132,34 +132,6 @@ typedef PRWord prword_t;
#define PR_ArenaCountRelease PL_ArenaCountRelease
#define PR_ArenaCountRetract PL_ArenaCountRetract
-/* Re: prevent.h->plevent.h */
-#define PREvent PLEvent
-#define PREventQueue PLEventQueue
-#define PR_CreateEventQueue PL_CreateEventQueue
-#define PR_DestroyEventQueue PL_DestroyEventQueue
-#define PR_GetEventQueueMonitor PL_GetEventQueueMonitor
-#define PR_ENTER_EVENT_QUEUE_MONITOR PL_ENTER_EVENT_QUEUE_MONITOR
-#define PR_EXIT_EVENT_QUEUE_MONITOR PL_EXIT_EVENT_QUEUE_MONITOR
-#define PR_PostEvent PL_PostEvent
-#define PR_PostSynchronousEvent PL_PostSynchronousEvent
-#define PR_GetEvent PL_GetEvent
-#define PR_EventAvailable PL_EventAvailable
-#define PREventFunProc PLEventFunProc
-#define PR_MapEvents PL_MapEvents
-#define PR_RevokeEvents PL_RevokeEvents
-#define PR_ProcessPendingEvents PL_ProcessPendingEvents
-#define PR_WaitForEvent PL_WaitForEvent
-#define PR_EventLoop PL_EventLoop
-#define PR_GetEventQueueSelectFD PL_GetEventQueueSelectFD
-#define PRHandleEventProc PLHandleEventProc
-#define PRDestroyEventProc PLDestroyEventProc
-#define PR_InitEvent PL_InitEvent
-#define PR_GetEventOwner PL_GetEventOwner
-#define PR_HandleEvent PL_HandleEvent
-#define PR_DestroyEvent PL_DestroyEvent
-#define PR_DequeueEvent PL_DequeueEvent
-#define PR_GetMainEventQueue PL_GetMainEventQueue
-
/* Re: prhash.h->plhash.h */
#define PRHashEntry PLHashEntry
#define PRHashTable PLHashTable
diff --git a/pr/include/prerr.h b/pr/include/prerr.h
index a2073435..a1fe2803 100644
--- a/pr/include/prerr.h
+++ b/pr/include/prerr.h
@@ -220,8 +220,8 @@
/* The file is busy */
#define PR_FILE_IS_BUSY_ERROR (-5936L)
-/* Reserved Error Code -5935 */
-#define PR_RESERVED_ERROR_5935 (-5935L)
+/* The I/O operation was aborted */
+#define PR_OPERATION_ABORTED_ERROR (-5935L)
/* Operation is still in progress (probably a non-blocking connect) */
#define PR_IN_PROGRESS_ERROR (-5934L)
diff --git a/pr/include/prinit.h b/pr/include/prinit.h
index 65fdb3ff..500182c3 100644
--- a/pr/include/prinit.h
+++ b/pr/include/prinit.h
@@ -44,10 +44,9 @@ PR_BEGIN_EXTERN_C
** The format of the version string is
** "<major version>.<minor version> <build date>"
*/
-#define PR_VERSION "3.5"
-#define PR_VMAJOR 3
-#define PR_VMAJOR_STR "3"
-#define PR_VMINOR 5
+#define PR_VERSION "4.0"
+#define PR_VMAJOR 4
+#define PR_VMINOR 0
#define PR_VPATCH 0
#define PR_BETA PR_FALSE
diff --git a/pr/include/prio.h b/pr/include/prio.h
index 75898729..36017128 100644
--- a/pr/include/prio.h
+++ b/pr/include/prio.h
@@ -104,9 +104,6 @@ typedef enum PRTransmitFileFlags {
#define PR_AF_INET AF_INET
#define PR_AF_LOCAL AF_UNIX
-#ifdef AF_INET6
-#define PR_AF_INET6 AF_INET6
-#endif
#define PR_INADDR_ANY INADDR_ANY
#define PR_INADDR_LOOPBACK INADDR_LOOPBACK
#define PR_INADDR_BROADCAST INADDR_BROADCAST
@@ -114,6 +111,15 @@ typedef enum PRTransmitFileFlags {
#endif /* WIN32 */
/*
+** Define PR_AF_INET6 in prcpucfg.h with the same
+** value as AF_INET6 on platforms with IPv6 support.
+** Otherwise define it here.
+*/
+#ifndef PR_AF_INET6
+#define PR_AF_INET6 100
+#endif
+
+/*
**************************************************************************
** A network address
**
@@ -122,15 +128,21 @@ typedef enum PRTransmitFileFlags {
** or IPv6 (AF_INET6).
**************************************************************************
*************************************************************************/
-#if defined(_PR_INET6)
-#if !defined(AF_INET6)
-#error "AF_INET6 is not defined"
-#endif
+struct PRIPv6Addr {
+ union {
+ PRUint8 _S6_u8[16];
+ PRUint16 _S6_u16[8];
+ PRUint32 _S6_u32[4];
+ PRUint64 _S6_u64[2];
+ } _S6_un;
+};
+#define pr_s6_addr _S6_un._S6_u8
+#define pr_s6_addr16 _S6_un._S6_u16
+#define pr_s6_addr32 _S6_un._S6_u32
+#define pr_s6_addr64 _S6_un._S6_addr64
-typedef struct in6_addr PRIPv6Addr;
-
-#endif /* defined(_PR_INET6) */
+typedef struct PRIPv6Addr PRIPv6Addr;
union PRNetAddr {
struct {
@@ -151,7 +163,6 @@ union PRNetAddr {
char pad[8];
#endif
} inet;
-#if defined(_PR_INET6)
struct {
PRUint16 family; /* address family (AF_INET6) */
PRUint16 port; /* port number */
@@ -159,7 +170,6 @@ union PRNetAddr {
PRIPv6Addr ip; /* the actual 128 bits of address */
PRUint32 scope_id; /* set of interfaces for a scope */
} ipv6;
-#endif /* defined(_PR_INET6) */
#if defined(XP_UNIX)
struct { /* Unix domain socket address */
PRUint16 family; /* address family (AF_UNIX) */
@@ -181,12 +191,17 @@ union PRNetAddr {
#else
#if defined(XP_UNIX)
-#define PR_NETADDR_SIZE(_addr) \
- ((_addr)->raw.family == AF_UNIX \
- ? sizeof((_addr)->local) \
- : sizeof((_addr)->inet))
+#define PR_NETADDR_SIZE(_addr) \
+ ((_addr)->raw.family == PR_AF_INET \
+ ? sizeof((_addr)->inet) \
+ : ((_addr)->raw.family == PR_AF_INET6 \
+ ? sizeof((_addr)->ipv6) \
+ : sizeof((_addr)->local)))
#else
-#define PR_NETADDR_SIZE(_addr) sizeof((_addr)->inet)
+#define PR_NETADDR_SIZE(_addr) \
+ ((_addr)->raw.family == PR_AF_INET \
+ ? sizeof((_addr)->inet) \
+ : sizeof((_addr)->ipv6))
#endif /* defined(XP_UNIX) */
#endif /* defined(_PR_INET6) */
@@ -351,10 +366,6 @@ typedef PRInt32 (PR_CALLBACK *PRTransmitfileFN)(
PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime t);
typedef PRStatus (PR_CALLBACK *PRGetsocknameFN)(PRFileDesc *fd, PRNetAddr *addr);
typedef PRStatus (PR_CALLBACK *PRGetpeernameFN)(PRFileDesc *fd, PRNetAddr *addr);
-typedef PRStatus (PR_CALLBACK *PRGetsockoptFN)( /* OBSOLETE */
- PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32 *optlen);
-typedef PRStatus (PR_CALLBACK *PRSetsockoptFN)( /* OBSOLETE */
- PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen);
typedef PRStatus (PR_CALLBACK *PRGetsocketoptionFN)(
PRFileDesc *fd, PRSocketOptionData *data);
typedef PRStatus (PR_CALLBACK *PRSetsocketoptionFN)(
@@ -391,8 +402,8 @@ struct PRIOMethods {
PRTransmitfileFN transmitfile; /* Transmit at entire file */
PRGetsocknameFN getsockname; /* Get (net) address associated with fd */
PRGetpeernameFN getpeername; /* Get peer's (net) address */
- PRGetsockoptFN getsockopt; /* OBSOLETE */
- PRSetsockoptFN setsockopt; /* OBSOLETE */
+ PRReservedFN reserved_fn_6; /* reserved for future use */
+ PRReservedFN reserved_fn_5; /* reserved for future use */
PRGetsocketoptionFN getsocketoption;
/* Get current setting of specified option */
PRSetsocketoptionFN setsocketoption;
@@ -574,7 +585,6 @@ NSPR_API(PRFileDesc*) PR_PopIOLayer(PRFileDesc *fd_stack, PRDescIdentity id);
**************************************************************************
*/
-NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode);
/* Open flags */
#define PR_RDONLY 0x01
#define PR_WRONLY 0x02
@@ -588,8 +598,8 @@ NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode);
/*
** File modes ....
**
-** CAVEAT: 'mode' is currently only applicable on UNIX platforms. We are
-** still in the process of seeing how these apply to other file systems.
+** CAVEAT: 'mode' is currently only applicable on UNIX platforms.
+** The 'mode' argument may be ignored by PR_Open on other platforms.
**
** 00400 Read by owner.
** 00200 Write by owner.
@@ -603,6 +613,35 @@ NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode);
**
*/
+NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode);
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_OpenFile
+ * DESCRIPTION:
+ * Open a file for reading, writing, or both.
+ * PR_OpenFile has the same prototype as PR_Open but implements
+ * the specified file mode where possible.
+ **************************************************************************
+ */
+
+/* File mode bits */
+#define PR_IRWXU 00700 /* read, write, execute/search by owner */
+#define PR_IRUSR 00400 /* read permission, owner */
+#define PR_IWUSR 00200 /* write permission, owner */
+#define PR_IXUSR 00100 /* execute/search permission, owner */
+#define PR_IRWXG 00070 /* read, write, execute/search by group */
+#define PR_IRGRP 00040 /* read permission, group */
+#define PR_IWGRP 00020 /* write permission, group */
+#define PR_IXGRP 00010 /* execute/search permission, group */
+#define PR_IRWXO 00007 /* read, write, execute/search by others */
+#define PR_IROTH 00004 /* read permission, others */
+#define PR_IWOTH 00002 /* write permission, others */
+#define PR_IXOTH 00001 /* execute/search permission, others */
+
+NSPR_API(PRFileDesc*) PR_OpenFile(
+ const char *name, PRIntn flags, PRIntn mode);
+
/*
**************************************************************************
* FUNCTION: PR_Close
@@ -1039,6 +1078,18 @@ 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.
@@ -1529,7 +1580,8 @@ NSPR_API(PRInt32) PR_SendFile(
** void *buf
** A pointer to a buffer to receive data sent by the client. This
** buffer must be large enough to receive <amount> bytes of data
-** and two PRNetAddr structures, plus an extra 32 bytes.
+** and two PRNetAddr structures, plus an extra 32 bytes. See:
+** PR_ACCEPT_READ_BUF_OVERHEAD.
** PRInt32 amount
** The number of bytes of client data to receive. Does not include
** the size of the PRNetAddr structures. If 0, no data will be read
@@ -1552,7 +1604,16 @@ NSPR_API(PRInt32) PR_SendFile(
** 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);
diff --git a/pr/include/pripcsem.h b/pr/include/pripcsem.h
index 4a75d68e..8b15ee96 100644
--- a/pr/include/pripcsem.h
+++ b/pr/include/pripcsem.h
@@ -38,6 +38,7 @@
#define pripcsem_h___
#include "prtypes.h"
+#include "prio.h"
PR_BEGIN_EXTERN_C
diff --git a/pr/include/private/pprio.h b/pr/include/private/pprio.h
index 37877ea3..4c12af38 100644
--- a/pr/include/private/pprio.h
+++ b/pr/include/private/pprio.h
@@ -208,18 +208,6 @@ NSPR_API(void) PR_NTFast_UpdateAcceptContext(PRFileDesc *acceptSock,
PRFileDesc *listenSock);
-/* FUNCTION: PR_NT_UseNonblock
-** DESCRIPTION:
-** This function only works on NT. It tells nspr to use nonblocking io
-** rather than async IO. There is no way to use some of each. This
-** function should be called immediately after calling PR_Init().
-**
-** WARNING: THIS FUNCTION IS A TEMPORARY HACK AND WILL BE REMOVED SHORTLY
-** (LIKE ALL FUNCTIONS IN THE PRIVATE AREA). DO NOT USE THIS FUNCTION AT
-** ALL WITHOUT CONTACTING mbelshe@netscape.com.
-*/
-NSPR_API(void) PR_NT_UseNonblock();
-
/* FUNCTION: PR_NT_CancelIo
** DESCRIPTION:
** Cancel IO operations on fd.
@@ -229,6 +217,15 @@ NSPR_API(PRStatus) PR_NT_CancelIo(PRFileDesc *fd);
#endif /* WIN32 */
+/*
+** Need external access to this on Mac so we can first set up our faux
+** environment vars
+*/
+#ifdef XP_MAC
+NSPR_API(void) PR_Init_Log(void);
+#endif
+
+
PR_END_EXTERN_C
#endif /* pprio_h___ */
diff --git a/pr/include/private/primpl.h b/pr/include/private/primpl.h
index ad468d2c..926c2585 100644
--- a/pr/include/private/primpl.h
+++ b/pr/include/private/primpl.h
@@ -186,11 +186,6 @@ struct _PT_Notified
typedef struct PTDebug
{
PRTime timeStarted;
- PRUintn predictionsFoiled;
- PRUintn pollingListMax;
- PRUintn continuationsServed;
- PRUintn recyclesNeeded;
- PRUintn quiescentIO;
PRUintn locks_created, locks_destroyed;
PRUintn locks_acquired, locks_released;
PRUintn cvars_created, cvars_destroyed;
@@ -1035,6 +1030,9 @@ extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd);
extern PRInt32 _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode);
#define _PR_MD_OPEN _MD_OPEN
+extern PRInt32 _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode);
+#define _PR_MD_OPEN_FILE _MD_OPEN_FILE
+
extern PRInt32 _PR_MD_CLOSE_FILE(PRInt32 osfd);
#define _PR_MD_CLOSE_FILE _MD_CLOSE_FILE
@@ -1067,6 +1065,9 @@ extern PRInt32 _PR_MD_STAT(const char *name, struct stat *buf);
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
@@ -1421,9 +1422,7 @@ struct PRThread {
#if defined(_PR_PTHREADS)
pthread_t id; /* pthread identifier for the thread */
PRBool okToDelete; /* ok to delete the PRThread struct? */
- PRCondVar *io_cv; /* a condition used to run i/o */
PRCondVar *waiting; /* where the thread is waiting | NULL */
- PRIntn io_tq_index; /* the io-queue index for this thread */
void *sp; /* recorded sp for garbage collection */
PRThread *next, *prev; /* simple linked list of all threads */
PRUint32 suspend; /* used to store suspend and resume flags */
@@ -1549,36 +1548,8 @@ struct PRFilePrivate {
PRFileDesc *next;
PRIntn lockCount;
_MDFileDesc md;
-#ifdef _PR_PTHREADS
- PRIntn eventMask[1]; /* An array of _pt_tq_count bitmasks.
- * eventMask[i] is only accessed by
- * the i-th i/o continuation thread.
- * A 0 in a bitmask means the event
- * should be igored in the revents
- * bitmask returned by poll.
- *
- * poll's revents bitmask is a short,
- * but we need to declare eventMask
- * as an array of PRIntn's so that
- * each bitmask can be updated
- * individually without disturbing
- * adjacent memory. Only the lower
- * 16 bits of each PRIntn are used. */
-#endif
-/* IMPORTANT: eventMask MUST BE THE LAST FIELD OF THIS STRUCTURE */
};
-/*
- * The actual size of the PRFilePrivate structure,
- * including the eventMask array at the end
- */
-#ifdef _PR_PTHREADS
-extern PRIntn _pt_tq_count;
-#define PRFILEPRIVATE_SIZE (sizeof(PRFilePrivate) + (_pt_tq_count-1) * sizeof(PRIntn))
-#else
-#define PRFILEPRIVATE_SIZE sizeof(PRFilePrivate)
-#endif
-
struct PRDir {
PRDirEntry d;
_MDDir md;
@@ -1674,10 +1645,6 @@ extern PRFileDesc *_pr_stdin;
extern PRFileDesc *_pr_stdout;
extern PRFileDesc *_pr_stderr;
-#if defined(_PR_INET6)
-extern PRBool _pr_ipv6_enabled; /* defined in prnetdb.c */
-#endif
-
/* Overriding malloc, free, etc. */
#if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \
&& !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) \
diff --git a/pr/include/prlink_mac.h b/pr/include/prlink_mac.h
deleted file mode 100644
index 117d51ec..00000000
--- a/pr/include/prlink_mac.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*
- * The contents of this file are subject to the Netscape Public License
- * Version 1.1 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
-
-#ifndef prlink_mac_h___
-#define prlink_mac_h___
-
-#ifdef XP_MAC
-
-#include <Files.h>
-#include "prtypes.h"
-
-PR_BEGIN_EXTERN_C
-
-/*
-** PR_LoadNamedFragment
-**
-** Load a code fragment by fragment name from the data fork of the specified file.
-** The fragment name is an internal name which uniquely identifies a code
-** fragment; this call opens the 'cfrg' resource in the file to find the
-** offsets of the named fragment.
-**
-** If the specified fragment exists, it is loaded and an entry created
-** in the load map (keyed by fragment name).
-**
-** If fileSpec points to an alias, the alias is resolved by this call.
-*/
-NSPR_API(PRLibrary*) PR_LoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName);
-
-/*
-** PR_LoadIndexedFragment
-**
-** Load a code fragment by fragment index from the data fork of the specified file
-** (since Mac shared libraries can contain multiple code fragments).
-** This call opens the 'cfrg' resource in the file to find the offsets
-** of the named fragment.
-**
-** If the specified fragment exists, it is loaded and an entry created
-** in the load map (keyed by fragment name).
-**
-** If fileSpec points to an alias, the alias is resolved by this call.
-**
-*/
-NSPR_API(PRLibrary*) PR_LoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragIndex);
-
-PR_END_EXTERN_C
-
-#endif
-
-
-#endif /* prlink_mac_h___ */
diff --git a/pr/include/prlog.h b/pr/include/prlog.h
index 19abcb96..7e242c0c 100644
--- a/pr/include/prlog.h
+++ b/pr/include/prlog.h
@@ -170,12 +170,6 @@ NSPR_API(void) PR_LogPrint(const char *fmt, ...);
*/
NSPR_API(void) PR_LogFlush(void);
-/* Need external access to this on Mac so we can first set up our faux environment vars */
-#ifdef XP_MAC
-NSPR_API(void) PR_Init_Log(void);
-#endif
-
-
/*
** Windoze 16 can't support a large static string space for all of the
** various debugging strings so logging is not enabled for it.
diff --git a/pr/include/prlong.h b/pr/include/prlong.h
index 1f2ad727..0d98622a 100644
--- a/pr/include/prlong.h
+++ b/pr/include/prlong.h
@@ -188,10 +188,10 @@ NSPR_API(PRInt64) LL_Zero(void);
#define LL_NE(a, b) (((a).hi != (b).hi) || ((a).lo != (b).lo))
#define LL_GE_ZERO(a) (((a).hi >> 31) == 0)
-#define LL_CMP(a, op, b) (((PRInt32)(a).hi op (PRInt32)(b).hi) || \
- (((a).hi == (b).hi) && ((a).lo op (b).lo)))
-#define LL_UCMP(a, op, b) (((a).hi op (b).hi) || \
- (((a).hi == (b).hi) && ((a).lo op (b).lo)))
+#define LL_CMP(a, op, b) (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \
+ ((PRInt32)(a).hi op (PRInt32)(b).hi))
+#define LL_UCMP(a, op, b) (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \
+ ((a).hi op (b).hi))
#define LL_AND(r, a, b) ((r).lo = (a).lo & (b).lo, \
(r).hi = (a).hi & (b).hi)
diff --git a/pr/include/prnetdb.h b/pr/include/prnetdb.h
index f729c422..df17daf7 100644
--- a/pr/include/prnetdb.h
+++ b/pr/include/prnetdb.h
@@ -117,13 +117,11 @@ NSPR_API(PRStatus) PR_GetHostByName(
** for the failure can be retrieved by PR_GetError().
***********************************************************************/
-/*
- * #define PR_AI_ALL 0x08
- * #define PR_AI_V4MAPPED 0x10
- * #define PR_AI_ADDRCONFIG 0x20
- * #define PR_AI_DEFAULT (PR_AI_V4MAPPED | PR_AI_ADDRCONFIG)
- */
-#define PR_AI_DEFAULT 0x30
+
+#define PR_AI_ALL 0x08
+#define PR_AI_V4MAPPED 0x10
+#define PR_AI_ADDRCONFIG 0x20
+#define PR_AI_DEFAULT (PR_AI_V4MAPPED | PR_AI_ADDRCONFIG)
NSPR_API(PRStatus) PR_GetIPNodeByName(
const char *hostname,
@@ -217,7 +215,8 @@ typedef enum PRNetAddrValue
{
PR_IpAddrNull, /* do NOT overwrite the IP address */
PR_IpAddrAny, /* assign logical INADDR_ANY to IP address */
- PR_IpAddrLoopback /* assign logical INADDR_LOOPBACK */
+ PR_IpAddrLoopback, /* assign logical INADDR_LOOPBACK */
+ PR_IpAddrV4Mapped /* IPv4 mapped address */
} PRNetAddrValue;
NSPR_API(PRStatus) PR_InitializeNetAddr(
@@ -267,6 +266,23 @@ NSPR_API(PRStatus) PR_SetNetAddr(
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.
@@ -290,12 +306,8 @@ NSPR_API(PRBool) PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val);
** RETURN:
** PRUint16 The 'port' field of 'addr'.
***********************************************************************/
-#ifdef _PR_INET6
#define PR_NetAddrInetPort(addr) \
((addr)->raw.family == PR_AF_INET6 ? (addr)->ipv6.port : (addr)->inet.port)
-#else
-#define PR_NetAddrInetPort(addr) ((addr)->inet.port)
-#endif
/***********************************************************************
** FUNCTION:
@@ -358,28 +370,6 @@ NSPR_API(PRStatus) PR_GetProtoByNumber(
PRInt32 protocolnumber, char* buffer, PRInt32 bufsize, PRProtoEnt* result);
/***********************************************************************
-** FUNCTION:
-** DESCRIPTION: PR_SetIPv6Enable()
-** Enable IPv6 capability on a platform that supports the architecture.
-**
-** Note: IPv6 must first be enabled for the host platform. If it is not,
-** the function will always return PR_FAILURE on any attempt to
-** change the setting.
-**
-** INPUTS:
-** PRBool itIs
-** Assign it a value of PR_TRUE to turn on IPv6
-** addressing, PR_FALSE to turn it off.
-** RETURN:
-** PRStatus PR_SUCCESS if the IPv6 is enabled for this particular
-** host. Otherwise it will return failure and GetError()
-** will confirm the result by indicating that the
-** protocol is not supported
-** (PR_PROTOCOL_NOT_SUPPORTED_ERROR)
-***********************************************************************/
-NSPR_API(PRStatus) PR_SetIPv6Enable(PRBool itIs);
-
-/***********************************************************************
** FUNCTIONS: PR_ntohs, PR_ntohl, PR_ntohll, PR_htons, PR_htonl, PR_htonll
**
** DESCRIPTION: API entries for the common byte ordering routines.
@@ -399,14 +389,6 @@ NSPR_API(PRUint16) PR_htons(PRUint16);
NSPR_API(PRUint32) PR_htonl(PRUint32);
NSPR_API(PRUint64) PR_htonll(PRUint64);
-/***********************************************************************
-** FUNCTION: PR_FamilyInet
-**
-** DESCRIPTION: Routine to get value of address family for Internet Protocol
-**
-***********************************************************************/
-NSPR_API(PRUint16) PR_FamilyInet(void);
-
PR_END_EXTERN_C
#endif /* prnetdb_h___ */
diff --git a/pr/include/prrng.h b/pr/include/prrng.h
index fa248e77..c6ad1333 100644
--- a/pr/include/prrng.h
+++ b/pr/include/prrng.h
@@ -16,49 +16,10 @@
* Reserved.
*/
-/*
-** Delete this section of the header after (if) agreement is reached to
-** provide the service suggested here. Move some parts of it, if
-** appropriate to platform specific implementation files.
-**
-** Proposal: Nothing in this header file should be construed as a
-** commitment on the part of the NSPR team, Netsacpe/AOL/Sun Alliance
-** et.al. to provide the API or function suggested in this header file.
-** This is a proposal, a draft, yadda. ... So, don't count on it.
-** lth. 29-Oct-1999
-**
-** --------------------------------------------------------------------
-**
-** Requirements, Discussion:
-**
-** Goal: foreach platform, find at least 160 bits of "good noise", that
-** is: from the platform itself, not extrapolated, stired, hashed,
-** xor'd, whatever, from a little available noise.
-**
-**
-** Required on the following platforms:
-** MAC, Win9x, WinNT, Solaris, Linux (k: 2.2.x).
-** Best effort on:
-** AIX, HP-UX.
-** Not required on:
-** Tru65 Unix (Compaq)
-**
-** Notes:
-**
-** I presume it is legal to put this function on Mozilla.org,
-** that it is not regulated as "cryptographic 'munitions'".
-**
-** Cartman says they need it 15-Jan-2000.
-**
-** --------------------------------------------------------------------
-*/
/*
** prrng.h -- NSPR Random Number Generator
**
-**
-**
-**
**
** lth. 29-Oct-1999.
*/
@@ -113,8 +74,7 @@ PR_BEGIN_EXTERN_C
** History:
** Parts of the model dependent implementation for PR_GetRandomNoise()
** were taken in whole or part from code previously in Netscape's NSS
-** component. There is no Goddamned Goverenment Munitions is this
-** code. Clinton: FOAD.
+** component.
**
*/
NSPR_API(PRSize) PR_GetRandomNoise(
diff --git a/pr/include/prshm.h b/pr/include/prshm.h
index d16cfce1..ae28e014 100644
--- a/pr/include/prshm.h
+++ b/pr/include/prshm.h
@@ -113,6 +113,7 @@
#define prshm_h___
#include "prtypes.h"
+#include "prio.h"
PR_BEGIN_EXTERN_C
diff --git a/pr/include/prtpool.h b/pr/include/prtpool.h
index 82ce2663..838031fc 100644
--- a/pr/include/prtpool.h
+++ b/pr/include/prtpool.h
@@ -22,9 +22,14 @@
#include "prtypes.h"
#include "prthread.h"
#include "prio.h"
-#include "prerr.h"
#include "prerror.h"
+/*
+ * NOTE:
+ * THIS API IS A PRELIMINARY VERSION IN NSPR 4.0 AND IS SUBJECT TO
+ * CHANGE
+ */
+
PR_BEGIN_EXTERN_C
typedef struct PRJobIoDesc {
@@ -35,50 +40,55 @@ typedef struct PRJobIoDesc {
typedef struct PRThreadPool PRThreadPool;
typedef struct PRJob PRJob;
-typedef void (PR_CALLBACK *JobFn) (void *arg);
+typedef void (PR_CALLBACK *PRJobFn) (void *arg);
/* Create thread pool */
-PR_EXTERN(PRThreadPool *)
+NSPR_API(PRThreadPool *)
PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads,
- PRSize stacksize);
+ PRUint32 stacksize);
/* queue a job */
-PR_EXTERN(PRJob *)
-PR_QueueJob(PRThreadPool *tpool, JobFn fn, void *arg, PRBool joinable);
+NSPR_API(PRJob *)
+PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable);
/* queue a job, when a socket is readable */
-PR_EXTERN(PRJob *)
+NSPR_API(PRJob *)
PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod,
- JobFn fn, void * arg, PRBool joinable);
+ PRJobFn fn, void * arg, PRBool joinable);
/* queue a job, when a socket is writeable */
-PR_EXTERN(PRJob *)
+NSPR_API(PRJob *)
PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod,
- JobFn fn, void * arg, PRBool joinable);
+ PRJobFn fn, void * arg, PRBool joinable);
/* queue a job, when a socket has a pending connection */
-PR_EXTERN(PRJob *)
+NSPR_API(PRJob *)
PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod,
- JobFn fn, void * arg, PRBool joinable);
+ PRJobFn fn, void * arg, PRBool joinable);
+
+/* queue a job, when the socket connection to addr succeeds or fails */
+NSPR_API(PRJob *)
+PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod,
+ const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable);
/* queue a job, when a timer exipres */
-PR_EXTERN(PRJob *)
+NSPR_API(PRJob *)
PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout,
- JobFn fn, void * arg, PRBool joinable);
+ PRJobFn fn, void * arg, PRBool joinable);
/* cancel a job */
-PR_EXTERN(PRStatus)
+NSPR_API(PRStatus)
PR_CancelJob(PRJob *job);
/* join a job */
-PR_EXTERN(PRStatus)
+NSPR_API(PRStatus)
PR_JoinJob(PRJob *job);
/* shutdown pool */
-PR_EXTERN(PRStatus)
+NSPR_API(PRStatus)
PR_ShutdownThreadPool(PRThreadPool *tpool);
/* join pool, wait for exit of all threads */
-PR_EXTERN(PRStatus)
+NSPR_API(PRStatus)
PR_JoinThreadPool(PRThreadPool *tpool);
PR_END_EXTERN_C
diff --git a/pr/include/prvrsion.h b/pr/include/prvrsion.h
index 7bd8d464..e5ad037f 100755
--- a/pr/include/prvrsion.h
+++ b/pr/include/prvrsion.h
@@ -74,9 +74,19 @@ typedef struct {
/*
* All components must define an entrypoint named libVersionPoint which
* is of type versionEntryPointType.
+ *
+ * For example, for a library named libfoo, we would have:
+ *
+ * PRVersionDescription prVersionDescription_libfoo =
+ * {
+ * ...
+ * };
+ *
+ * PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void)
+ * {
+ * return &prVersionDescription_libfoo;
+ * }
*/
-NSPR_API(const PRVersionDescription *) libVersionPoint(void);
-
typedef const PRVersionDescription *(*versionEntryPointType)(void);
/*
diff --git a/pr/src/Makefile b/pr/src/Makefile
index 808f98aa..9f584e48 100644
--- a/pr/src/Makefile
+++ b/pr/src/Makefile
@@ -141,7 +141,7 @@ endif
ifeq ($(OS_ARCH),WINNT)
ifneq ($(OS_TARGET),WIN16)
-OS_LIBS = wsock32.lib winmm.lib
+OS_LIBS = advapi32.lib wsock32.lib winmm.lib
endif
endif
@@ -155,6 +155,7 @@ OBJS = \
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) \
@@ -227,10 +228,6 @@ endif
endif
-ifeq ($(USE_IPV6), 1)
-OBJS += io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX)
-endif
-
ifeq ($(USE_CPLUS), 1)
OBJS += \
cplus/$(OBJDIR)/rcbase.$(OBJ_SUFFIX) \
@@ -289,6 +286,7 @@ OBJS += md/windows/$(OBJDIR)/w95io.$(OBJ_SUFFIX) \
md/windows/$(OBJDIR)/ntgc.$(OBJ_SUFFIX) \
md/windows/$(OBJDIR)/ntmisc.$(OBJ_SUFFIX) \
md/windows/$(OBJDIR)/ntinrval.$(OBJ_SUFFIX) \
+ md/windows/$(OBJDIR)/ntsec.$(OBJ_SUFFIX) \
md/windows/$(OBJDIR)/ntsem.$(OBJ_SUFFIX) \
md/windows/$(OBJDIR)/win32_errors.$(OBJ_SUFFIX) \
md/windows/$(OBJDIR)/w32ipcsem.$(OBJ_SUFFIX) \
@@ -303,6 +301,7 @@ OBJS += md/windows/$(OBJDIR)/ntdllmn.$(OBJ_SUFFIX) \
md/windows/$(OBJDIR)/ntthread.$(OBJ_SUFFIX) \
md/windows/$(OBJDIR)/ntmisc.$(OBJ_SUFFIX) \
md/windows/$(OBJDIR)/ntinrval.$(OBJ_SUFFIX) \
+ md/windows/$(OBJDIR)/ntsec.$(OBJ_SUFFIX) \
md/windows/$(OBJDIR)/ntsem.$(OBJ_SUFFIX) \
md/windows/$(OBJDIR)/win32_errors.$(OBJ_SUFFIX) \
md/windows/$(OBJDIR)/w32ipcsem.$(OBJ_SUFFIX) \
diff --git a/pr/src/Makefile.in b/pr/src/Makefile.in
index de397356..bad88779 100644
--- a/pr/src/Makefile.in
+++ b/pr/src/Makefile.in
@@ -162,6 +162,7 @@ OBJS = \
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) \
@@ -229,10 +230,6 @@ endif
endif
-ifeq ($(USE_IPV6), 1)
-OBJS += io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX)
-endif
-
ifeq ($(USE_CPLUS), 1)
OBJS += \
cplus/$(OBJDIR)/rcbase.$(OBJ_SUFFIX) \
diff --git a/pr/src/io/Makefile b/pr/src/io/Makefile
index 692976e7..d9cc321b 100644
--- a/pr/src/io/Makefile
+++ b/pr/src/io/Makefile
@@ -32,6 +32,7 @@ CSRCS = \
prfdcach.c \
prmwait.c \
priometh.c \
+ pripv6.c \
prmapopt.c \
prlayer.c \
prlog.c \
@@ -51,10 +52,6 @@ ifndef USE_PTHREADS
$(NULL)
endif
-ifdef USE_IPV6
-CSRCS += pripv6.c
-endif
-
TARGETS = $(OBJS)
INCLUDES = -I$(DIST)/include -I$(MOD_DEPTH)/pr/include -I$(MOD_DEPTH)/pr/include/private
diff --git a/pr/src/io/Makefile.in b/pr/src/io/Makefile.in
index 40be6e7d..b4272a8a 100644
--- a/pr/src/io/Makefile.in
+++ b/pr/src/io/Makefile.in
@@ -37,6 +37,7 @@ CSRCS = \
prfdcach.c \
prmwait.c \
priometh.c \
+ pripv6.c \
prmapopt.c \
prlayer.c \
prlog.c \
@@ -56,10 +57,6 @@ ifndef USE_PTHREADS
$(NULL)
endif
-ifdef USE_IPV6
-CSRCS += pripv6.c
-endif
-
TARGETS = $(OBJS)
INCLUDES = -I$(DIST)/include -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
diff --git a/pr/src/io/prdir.c b/pr/src/io/prdir.c
index 0576aa9a..1d2b6958 100644
--- a/pr/src/io/prdir.c
+++ b/pr/src/io/prdir.c
@@ -70,6 +70,18 @@ PRInt32 rv;
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;
diff --git a/pr/src/io/prfdcach.c b/pr/src/io/prfdcach.c
index 6ad2e84c..00947d31 100644
--- a/pr/src/io/prfdcach.c
+++ b/pr/src/io/prfdcach.c
@@ -115,14 +115,14 @@ finished:
fd->dtor = NULL;
fd->lower = fd->higher = NULL;
fd->identity = PR_NSPR_IO_LAYER;
- memset(fd->secret, 0, PRFILEPRIVATE_SIZE);
+ memset(fd->secret, 0, sizeof(PRFilePrivate));
return fd;
allocate:
fd = PR_NEW(PRFileDesc);
if (NULL != fd)
{
- fd->secret = (PRFilePrivate *) PR_MALLOC(PRFILEPRIVATE_SIZE);
+ fd->secret = PR_NEW(PRFilePrivate);
if (NULL == fd->secret) PR_DELETE(fd);
}
if (NULL != fd) goto finished;
diff --git a/pr/src/io/prfile.c b/pr/src/io/prfile.c
index accc618b..3365df39 100644
--- a/pr/src/io/prfile.c
+++ b/pr/src/io/prfile.c
@@ -268,8 +268,8 @@ static PRIOMethods _pr_fileMethods = {
(PRTransmitfileFN)_PR_InvalidInt,
(PRGetsocknameFN)_PR_InvalidStatus,
(PRGetpeernameFN)_PR_InvalidStatus,
- (PRGetsockoptFN)_PR_InvalidStatus,
- (PRSetsockoptFN)_PR_InvalidStatus,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
@@ -312,8 +312,8 @@ static PRIOMethods _pr_pipeMethods = {
(PRTransmitfileFN)_PR_InvalidInt,
(PRGetsocknameFN)_PR_InvalidStatus,
(PRGetpeernameFN)_PR_InvalidStatus,
- (PRGetsockoptFN)_PR_InvalidStatus,
- (PRSetsockoptFN)_PR_InvalidStatus,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
@@ -348,6 +348,26 @@ PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)
return fd;
}
+PR_IMPLEMENT(PRFileDesc*) PR_OpenFile(
+ const char *name, PRIntn flags, PRIntn mode)
+{
+ PRInt32 osfd;
+ PRFileDesc *fd = 0;
+
+ if (!_pr_initialized) _PR_ImplicitInitialization();
+
+ /* Map pr open flags and mode to os specific flags */
+
+ osfd = _PR_MD_OPEN_FILE(name, flags, mode);
+ if (osfd != -1) {
+ fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
+ if (!fd) {
+ (void) _PR_MD_CLOSE_FILE(osfd);
+ }
+ }
+ return fd;
+}
+
PRInt32 PR_GetSysfdTableMax(void)
{
#if defined(XP_UNIX) && !defined(AIX) && !defined(NEXTSTEP) && !defined(QNX)
diff --git a/pr/src/io/priometh.c b/pr/src/io/priometh.c
index 0203d28b..b52990a7 100644
--- a/pr/src/io/priometh.c
+++ b/pr/src/io/priometh.c
@@ -48,8 +48,8 @@ PRIOMethods _pr_faulty_methods = {
(PRTransmitfileFN)_PR_InvalidInt,
(PRGetsocknameFN)_PR_InvalidStatus,
(PRGetpeernameFN)_PR_InvalidStatus,
- (PRGetsockoptFN)_PR_InvalidStatus,
- (PRSetsockoptFN)_PR_InvalidStatus,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
@@ -247,26 +247,6 @@ PR_IMPLEMENT(PRStatus) PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
return((fd->methods->getpeername)(fd,addr));
}
-PR_IMPLEMENT(PRStatus) PR_GetSockOpt(
- PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen)
-{
-#if defined(DEBUG)
- static PRBool warn = PR_TRUE;
- if (warn) warn = _PR_Obsolete("PR_GetSockOpt()", "PR_GetSocketOption()");
-#endif
- return((fd->methods->getsockopt)(fd, optname, optval, optlen));
-}
-
-PR_IMPLEMENT(PRStatus) PR_SetSockOpt(
- PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen)
-{
-#if defined(DEBUG)
- static PRBool warn = PR_TRUE;
- if (warn) warn = _PR_Obsolete("PR_SetSockOpt()", "PR_SetSocketOption()");
-#endif
- return((fd->methods->setsockopt)(fd, optname, optval, optlen));
-}
-
PR_IMPLEMENT(PRStatus) PR_GetSocketOption(
PRFileDesc *fd, PRSocketOptionData *data)
{
diff --git a/pr/src/io/pripv6.c b/pr/src/io/pripv6.c
index 564648c0..485e449d 100644
--- a/pr/src/io/pripv6.c
+++ b/pr/src/io/pripv6.c
@@ -20,7 +20,341 @@
** 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)
-/* pripv6.c */
+static PRIOMethods ipv6_to_v4_tcpMethods;
+static PRIOMethods ipv6_to_v4_udpMethods;
+static PRDescIdentity _pr_ipv6_to_ipv4_id;
+extern PRBool IsValidNetAddr(const PRNetAddr *addr);
+extern PRIPv6Addr _pr_in6addr_any;
+extern PRIPv6Addr _pr_in6addr_loopback;
+/*
+ * convert an IPv4-mapped IPv6 addr to an IPv4 addr
+ */
+static void _PR_ConvertToIpv4NetAddr(const PRNetAddr *src_v6addr,
+ PRNetAddr *dst_v4addr)
+{
+const PRUint8 *srcp;
+
+ PR_ASSERT(PR_AF_INET6 == src_v6addr->ipv6.family);
+
+ if (PR_IsNetAddrType(src_v6addr, PR_IpAddrV4Mapped)) {
+ srcp = src_v6addr->ipv6.ip.pr_s6_addr;
+ memcpy((char *) &dst_v4addr->inet.ip, srcp + 12, 4);
+ } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrAny)) {
+ dst_v4addr->inet.ip = htonl(INADDR_ANY);
+ } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrLoopback)) {
+ dst_v4addr->inet.ip = htonl(INADDR_LOOPBACK);
+ }
+ dst_v4addr->inet.family = PR_AF_INET;
+ dst_v4addr->inet.port = src_v6addr->ipv6.port;
+}
+
+/*
+ * convert an IPv4 addr to an IPv4-mapped IPv6 addr
+ */
+static void _PR_ConvertToIpv6NetAddr(const PRNetAddr *src_v4addr,
+ PRNetAddr *dst_v6addr)
+{
+PRUint8 *dstp;
+
+ PR_ASSERT(PR_AF_INET == src_v4addr->inet.family);
+ dst_v6addr->ipv6.family = PR_AF_INET6;
+ dst_v6addr->ipv6.port = src_v4addr->inet.port;
+
+ if (htonl(INADDR_ANY) == src_v4addr->inet.ip) {
+ dst_v6addr->ipv6.ip = _pr_in6addr_any;
+ } else {
+ dstp = dst_v6addr->ipv6.ip.pr_s6_addr;
+ memset(dstp, 0, 10);
+ memset(dstp + 10, 0xff, 2);
+ memcpy(dstp + 12,(char *) &src_v4addr->inet.ip, 4);
+ }
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketBind(PRFileDesc *fd,
+ const PRNetAddr *addr)
+{
+ PRNetAddr tmp_ipv4addr;
+ const PRNetAddr *tmp_addrp;
+ PRFileDesc *lo = fd->lower;
+
+ if (PR_AF_INET6 != addr->raw.family) {
+ PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+ return PR_FAILURE;
+ }
+ if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
+ PR_IsNetAddrType(addr, PR_IpAddrAny)) {
+ _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
+ tmp_addrp = &tmp_ipv4addr;
+ } else {
+ PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
+ return PR_FAILURE;
+ }
+ return((lo->methods->bind)(lo,tmp_addrp));
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketConnect(
+ PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+ PRNetAddr tmp_ipv4addr;
+ const PRNetAddr *tmp_addrp;
+
+ if (PR_AF_INET6 != addr->raw.family) {
+ PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+ return PR_FAILURE;
+ }
+ if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
+ PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
+ _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
+ tmp_addrp = &tmp_ipv4addr;
+ } else {
+ PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
+ return PR_FAILURE;
+ }
+ return (fd->lower->methods->connect)(fd->lower, tmp_addrp, timeout);
+}
+
+static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketSendTo(
+ PRFileDesc *fd, const void *buf, PRInt32 amount,
+ PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+ PRNetAddr tmp_ipv4addr;
+ const PRNetAddr *tmp_addrp;
+
+ if (PR_AF_INET6 != addr->raw.family) {
+ PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+ return PR_FAILURE;
+ }
+ if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
+ PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
+ _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
+ tmp_addrp = &tmp_ipv4addr;
+ } else {
+ PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
+ return PR_FAILURE;
+ }
+ return (fd->lower->methods->sendto)(
+ fd->lower, buf, amount, flags, tmp_addrp, timeout);
+}
+
+static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept (
+ PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
+{
+ PRStatus rv;
+ PRFileDesc *newfd;
+ PRFileDesc *newstack;
+ PRNetAddr tmp_ipv4addr;
+
+ PR_ASSERT(fd != NULL);
+ PR_ASSERT(fd->lower != NULL);
+
+ newstack = PR_NEW(PRFileDesc);
+ if (NULL == newstack)
+ {
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ return NULL;
+ }
+ *newstack = *fd; /* make a copy of the accepting layer */
+
+ newfd = (fd->lower->methods->accept)(fd->lower, &tmp_ipv4addr, timeout);
+ if (NULL == newfd)
+ {
+ PR_DELETE(newstack);
+ return NULL;
+ }
+ _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, addr);
+
+ rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
+ PR_ASSERT(PR_SUCCESS == rv);
+ return newfd; /* that's it */
+}
+
+static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketAcceptRead(PRFileDesc *sd,
+ PRFileDesc **nd, PRNetAddr **ipv6_raddr, void *buf, PRInt32 amount,
+ PRIntervalTime timeout)
+{
+ PRInt32 nbytes;
+ PRStatus rv;
+ PRNetAddr tmp_ipv4addr;
+ PRFileDesc *newstack;
+
+ PR_ASSERT(sd != NULL);
+ PR_ASSERT(sd->lower != NULL);
+
+ newstack = PR_NEW(PRFileDesc);
+ if (NULL == newstack)
+ {
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ return -1;
+ }
+ *newstack = *sd; /* make a copy of the accepting layer */
+
+ nbytes = sd->lower->methods->acceptread(
+ sd->lower, nd, ipv6_raddr, buf, amount, timeout);
+ if (-1 == nbytes)
+ {
+ PR_DELETE(newstack);
+ return nbytes;
+ }
+ tmp_ipv4addr = **ipv6_raddr; /* copy */
+ _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, *ipv6_raddr);
+
+ /* this PR_PushIOLayer call cannot fail */
+ rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack);
+ PR_ASSERT(PR_SUCCESS == rv);
+ return nbytes;
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetName(PRFileDesc *fd,
+ PRNetAddr *ipv6addr)
+{
+ PRStatus result;
+ PRNetAddr tmp_ipv4addr;
+
+ result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr);
+ if (PR_SUCCESS == result) {
+ _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
+ PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
+ }
+ return result;
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetPeerName(PRFileDesc *fd,
+ PRNetAddr *ipv6addr)
+{
+ PRStatus result;
+ PRNetAddr tmp_ipv4addr;
+
+ result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr);
+ if (PR_SUCCESS == result) {
+ _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
+ PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
+ }
+ return result;
+}
+
+static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketRecvFrom(PRFileDesc *fd, void *buf,
+ PRInt32 amount, PRIntn flags, PRNetAddr *ipv6addr,
+ PRIntervalTime timeout)
+{
+ PRNetAddr tmp_ipv4addr;
+ PRInt32 result;
+
+ result = (fd->lower->methods->recvfrom)(
+ fd->lower, buf, amount, flags, &tmp_ipv4addr, timeout);
+ if (-1 != result) {
+ _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
+ PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
+ }
+ return result;
+}
+
+#if defined(_PR_INET6_PROBE)
+PRBool _pr_ipv6_is_present;
+PR_EXTERN(PRBool) _pr_test_ipv6_socket();
+#if defined(_PR_HAVE_GETIPNODEBYNAME)
+void *_pr_getipnodebyname_fp;
+void *_pr_getipnodebyaddr_fp;
+void *_pr_freehostent_fp;
+#endif
+#endif
+
+PRStatus _pr_init_ipv6()
+{
+ const PRIOMethods *stubMethods;
+
+#if defined(_PR_INET6_PROBE)
+
+#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
+ PRLibrary *lib;
+ _pr_getipnodebyname_fp = PR_FindSymbolAndLibrary("getipnodebyname", &lib);
+ if (NULL != _pr_getipnodebyname_fp) {
+ _pr_freehostent_fp = PR_FindSymbol(lib, "freehostent");
+ if (NULL != _pr_freehostent_fp) {
+ _pr_getipnodebyaddr_fp = PR_FindSymbol(lib, "getipnodebyaddr");
+ if (NULL != _pr_getipnodebyaddr_fp)
+ _pr_ipv6_is_present = PR_TRUE;
+ else
+ _pr_ipv6_is_present = PR_FALSE;
+ } else
+ _pr_ipv6_is_present = PR_FALSE;
+ (void)PR_UnloadLibrary(lib);
+ } else
+ _pr_ipv6_is_present = PR_FALSE;
+ if (PR_TRUE == _pr_ipv6_is_present)
+#endif
+
+ _pr_ipv6_is_present = _pr_test_ipv6_socket();
+ if (PR_TRUE == _pr_ipv6_is_present)
+ return PR_SUCCESS;
+#endif
+
+ _pr_ipv6_to_ipv4_id = PR_GetUniqueIdentity("Ipv6_to_Ipv4 layer");
+ PR_ASSERT(PR_INVALID_IO_LAYER != _pr_ipv6_to_ipv4_id);
+
+ stubMethods = PR_GetDefaultIOMethods();
+
+ ipv6_to_v4_tcpMethods = *stubMethods; /* first get the entire batch */
+ /* then override the ones we care about */
+ ipv6_to_v4_tcpMethods.connect = Ipv6ToIpv4SocketConnect;
+ ipv6_to_v4_tcpMethods.bind = Ipv6ToIpv4SocketBind;
+ ipv6_to_v4_tcpMethods.accept = Ipv6ToIpv4SocketAccept;
+ ipv6_to_v4_tcpMethods.acceptread = Ipv6ToIpv4SocketAcceptRead;
+ ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName;
+ ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
+/*
+ ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
+ ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
+*/
+ ipv6_to_v4_udpMethods = *stubMethods; /* first get the entire batch */
+ /* then override the ones we care about */
+ ipv6_to_v4_udpMethods.connect = Ipv6ToIpv4SocketConnect;
+ ipv6_to_v4_udpMethods.bind = Ipv6ToIpv4SocketBind;
+ ipv6_to_v4_udpMethods.sendto = Ipv6ToIpv4SocketSendTo;
+ ipv6_to_v4_udpMethods.recvfrom = Ipv6ToIpv4SocketRecvFrom;
+ ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName;
+ ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
+/*
+ ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
+ ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
+*/
+ return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd)
+{
+ PRFileDesc *ipv6_fd = NULL;
+
+ /*
+ * For platforms with no support for IPv6
+ * create layered socket for IPv4-mapped IPv6 addresses
+ */
+ if (fd->methods->file_type == PR_DESC_SOCKET_TCP)
+ ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id,
+ &ipv6_to_v4_tcpMethods);
+ else
+ ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id,
+ &ipv6_to_v4_udpMethods);
+ if (NULL == ipv6_fd) {
+ goto errorExit;
+ }
+ ipv6_fd->secret = NULL;
+
+ if (PR_PushIOLayer(fd, PR_TOP_IO_LAYER, ipv6_fd) == PR_FAILURE) {
+ goto errorExit;
+ }
+
+ return PR_SUCCESS;
+errorExit:
+
+ if (ipv6_fd)
+ ipv6_fd->dtor(ipv6_fd);
+ return PR_FAILURE;
+}
+
+#endif /* !defined(_PR_INET6) || defined(_PR_INET6_PROBE) */
diff --git a/pr/src/io/prlayer.c b/pr/src/io/prlayer.c
index 39a5d694..541b9be4 100644
--- a/pr/src/io/prlayer.c
+++ b/pr/src/io/prlayer.c
@@ -319,24 +319,6 @@ static PRStatus PR_CALLBACK pl_DefGetpeername (PRFileDesc *fd, PRNetAddr *addr)
return (fd->lower->methods->getpeername)(fd->lower, addr);
}
-static PRStatus PR_CALLBACK pl_DefGetsockopt (
- PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen)
-{
- PR_ASSERT(fd != NULL);
- PR_ASSERT(fd->lower != NULL);
-
- return (fd->lower->methods->getsockopt)(fd->lower, optname, optval, optlen);
-}
-
-static PRStatus PR_CALLBACK pl_DefSetsockopt (
- PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen)
-{
- PR_ASSERT(fd != NULL);
- PR_ASSERT(fd->lower != NULL);
-
- return (fd->lower->methods->setsockopt)(fd->lower, optname, optval, optlen);
-}
-
static PRStatus PR_CALLBACK pl_DefGetsocketoption (
PRFileDesc *fd, PRSocketOptionData *data)
{
@@ -394,8 +376,8 @@ static PRIOMethods pl_methods = {
pl_DefTransmitfile,
pl_DefGetsockname,
pl_DefGetpeername,
- pl_DefGetsockopt,
- pl_DefSetsockopt,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
pl_DefGetsocketoption,
pl_DefSetsocketoption,
pl_DefSendfile,
diff --git a/pr/src/io/prpolevt.c b/pr/src/io/prpolevt.c
index 3e26f226..0369ae7c 100644
--- a/pr/src/io/prpolevt.c
+++ b/pr/src/io/prpolevt.c
@@ -169,8 +169,8 @@ static PRIOMethods _pr_polevt_methods = {
(PRTransmitfileFN)_PR_InvalidInt,
(PRGetsocknameFN)_PR_InvalidStatus,
(PRGetpeernameFN)_PR_InvalidStatus,
- (PRGetsockoptFN)_PR_InvalidStatus,
- (PRSetsockoptFN)_PR_InvalidStatus,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
diff --git a/pr/src/io/prsocket.c b/pr/src/io/prsocket.c
index 69c61bb2..4ee568fd 100644
--- a/pr/src/io/prsocket.c
+++ b/pr/src/io/prsocket.c
@@ -25,16 +25,14 @@
/* These two functions are only used in assertions. */
#if defined(DEBUG)
-static PRBool IsValidNetAddr(const PRNetAddr *addr)
+PRBool IsValidNetAddr(const PRNetAddr *addr)
{
if ((addr != NULL)
#ifdef XP_UNIX
- && (addr->raw.family != AF_UNIX)
+ && (addr->raw.family != PR_AF_LOCAL)
#endif
-#ifdef _PR_INET6
- && (addr->raw.family != AF_INET6)
-#endif
- && (addr->raw.family != AF_INET)) {
+ && (addr->raw.family != PR_AF_INET6)
+ && (addr->raw.family != PR_AF_INET)) {
return PR_FALSE;
}
return PR_TRUE;
@@ -228,6 +226,10 @@ 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)) {
@@ -235,8 +237,15 @@ static PRStatus PR_CALLBACK SocketConnect(
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
return PR_FAILURE;
}
+#if defined(_PR_INET6)
+ if (addr->raw.family == PR_AF_INET6) {
+ addrCopy = *addr;
+ addrCopy.raw.family = AF_INET6;
+ addrp = &addrCopy;
+ }
+#endif
- rv = _PR_MD_CONNECT(fd, addr, PR_NETADDR_SIZE(addr), timeout);
+ rv = _PR_MD_CONNECT(fd, addrp, PR_NETADDR_SIZE(addr), timeout);
PR_LOG(_pr_io_lm, PR_LOG_MAX, ("connect -> %d", rv));
if (rv == 0)
return PR_SUCCESS;
@@ -414,6 +423,10 @@ PRIntervalTime timeout)
_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);
@@ -458,6 +471,10 @@ PRIntervalTime timeout)
PR_ASSERT(al == PR_NETADDR_SIZE(addr));
fd2->secret->md.accepted_socket = PR_TRUE;
memcpy(&fd2->secret->md.peer_addr, addr, al);
+#ifdef _PR_INET6
+ if (AF_INET6 == addr->raw.family)
+ addr->raw.family = PR_AF_INET6;
+#endif
}
return fd2;
}
@@ -467,6 +484,10 @@ PRIntervalTime timeout)
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);
@@ -480,7 +501,14 @@ static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr)
}
#endif /* XP_UNIX */
- result = _PR_MD_BIND(fd, addr, PR_NETADDR_SIZE(addr));
+#if defined(_PR_INET6)
+ if (addr->raw.family == PR_AF_INET6) {
+ addrCopy = *addr;
+ addrCopy.raw.family = AF_INET6;
+ addrp = &addrCopy;
+ }
+#endif
+ result = _PR_MD_BIND(fd, addrp, PR_NETADDR_SIZE(addr));
if (result < 0) {
return PR_FAILURE;
}
@@ -630,6 +658,10 @@ static PRInt32 PR_CALLBACK SocketSendTo(
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)) {
@@ -643,11 +675,18 @@ static PRInt32 PR_CALLBACK SocketSendTo(
}
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+#if defined(_PR_INET6)
+ if (addr->raw.family == PR_AF_INET6) {
+ addrCopy = *addr;
+ addrCopy.raw.family = AF_INET6;
+ addrp = &addrCopy;
+ }
+#endif
count = 0;
while (amount > 0) {
temp = _PR_MD_SENDTO(fd, buf, amount, flags,
- addr, PR_NETADDR_SIZE(addr), timeout);
+ addrp, PR_NETADDR_SIZE(addr), timeout);
if (temp < 0) {
count = -1;
break;
@@ -681,6 +720,10 @@ PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
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;
}
@@ -730,6 +773,10 @@ PRIntervalTime timeout)
(*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
}
}
}
@@ -779,6 +826,10 @@ PRIntervalTime timeout)
(*nd)->secret->md.accepted_socket = PR_TRUE;
memcpy(&(*nd)->secret->md.peer_addr, *raddr,
PR_NETADDR_SIZE(*raddr));
+#ifdef _PR_INET6
+ if (AF_INET6 == *raddr->raw.family)
+ *raddr->raw.family = PR_AF_INET6;
+#endif
}
}
return rv;
@@ -826,6 +877,10 @@ void *callbackArg)
(*nd)->secret->md.accepted_socket = PR_TRUE;
memcpy(&(*nd)->secret->md.peer_addr, *raddr,
PR_NETADDR_SIZE(*raddr));
+#ifdef _PR_INET6
+ if (AF_INET6 == *raddr->raw.family)
+ *raddr->raw.family = PR_AF_INET6;
+#endif
}
}
return rv;
@@ -910,6 +965,10 @@ static PRStatus PR_CALLBACK SocketGetName(PRFileDesc *fd, PRNetAddr *addr)
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;
@@ -925,121 +984,15 @@ static PRStatus PR_CALLBACK SocketGetPeerName(PRFileDesc *fd, PRNetAddr *addr)
if (result < 0) {
return PR_FAILURE;
}
+#ifdef _PR_INET6
+ if (AF_INET6 == addr->raw.family)
+ addr->raw.family = PR_AF_INET6;
+#endif
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
return PR_SUCCESS;
}
-static PRStatus PR_CALLBACK SocketGetSockOpt(
- PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen)
-{
- PRInt32 level, name;
- PRStatus rv;
-
- /*
- * PR_SockOpt_Nonblocking is a special case that does not
- * translate to a getsockopt() call
- */
- if (PR_SockOpt_Nonblocking == optname)
- {
- PR_ASSERT(sizeof(PRIntn) <= *optlen);
- *((PRIntn *) optval) = (PRIntn) fd->secret->nonblocking;
- *optlen = sizeof(PRIntn);
- return PR_SUCCESS;
- }
-
- rv = _PR_MapOptionName(optname, &level, &name);
- if (PR_SUCCESS == rv)
- {
- if (PR_SockOpt_Linger == optname)
- {
-#if !defined(XP_BEOS)
- struct linger linger;
- PRInt32 len = sizeof(linger);
- rv = _PR_MD_GETSOCKOPT(
- fd, level, name, (char *) &linger, &len);
- if (PR_SUCCESS == rv)
- {
- ((PRLinger*)(optval))->polarity = linger.l_onoff
- ? PR_TRUE : PR_FALSE;
- ((PRLinger*)(optval))->linger = PR_SecondsToInterval(
- linger.l_linger);
- *optlen = sizeof(PRLinger);
- }
-#else
- PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
- return PR_FAILURE;
-#endif
- }
- else
- {
- rv = _PR_MD_GETSOCKOPT(
- fd, level, name, (char*)optval, optlen);
- }
- }
- return rv;
-}
-
-static PRStatus PR_CALLBACK SocketSetSockOpt(
- PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen)
-{
- PRInt32 level, name;
- PRStatus rv;
-
- /*
- * PR_SockOpt_Nonblocking is a special case that does not
- * translate to a setsockopt call.
- */
- if (PR_SockOpt_Nonblocking == optname)
- {
- PRBool fNonblocking = *((PRIntn *) optval) ? PR_TRUE : PR_FALSE;
- PR_ASSERT(sizeof(PRIntn) == optlen);
-#ifdef WINNT
- PR_ASSERT((fd->secret->md.io_model_committed == PR_FALSE)
- || (fd->secret->nonblocking == fNonblocking));
- if (fd->secret->md.io_model_committed
- && (fd->secret->nonblocking != fNonblocking))
- {
- /*
- * On NT, once we have associated a socket with the io
- * completion port, we can't disassociate it. So we
- * can't change the nonblocking option of the socket
- * afterwards.
- */
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- return PR_FAILURE;
- }
-#endif
- fd->secret->nonblocking = fNonblocking;
- return PR_SUCCESS;
- }
-
- rv = _PR_MapOptionName(optname, &level, &name);
- if (PR_SUCCESS == rv)
- {
- if (PR_SockOpt_Linger == optname)
- {
-#if !defined(XP_BEOS)
- struct linger linger;
- linger.l_onoff = ((PRLinger*)(optval))->polarity ? 1 : 0;
- linger.l_linger = PR_IntervalToSeconds(
- ((PRLinger*)(optval))->linger);
- rv = _PR_MD_SETSOCKOPT(
- fd, level, name, (char *) &linger, sizeof(linger));
-#else
- PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
- return PR_FAILURE;
-#endif
- }
- else
- {
- rv = _PR_MD_SETSOCKOPT(
- fd, level, name, (const char*)optval, optlen);
- }
- }
- return rv;
-}
-
static PRInt16 PR_CALLBACK SocketPoll(
PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
{
@@ -1077,8 +1030,8 @@ static PRIOMethods tcpMethods = {
SocketTransmitFile,
SocketGetName,
SocketGetPeerName,
- SocketGetSockOpt,
- SocketSetSockOpt,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
_PR_SocketGetSocketOption,
_PR_SocketSetSocketOption,
SocketSendFile,
@@ -1116,8 +1069,8 @@ static PRIOMethods udpMethods = {
(PRTransmitfileFN)_PR_InvalidInt,
SocketGetName,
SocketGetPeerName,
- SocketGetSockOpt,
- SocketSetSockOpt,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
_PR_SocketGetSocketOption,
_PR_SocketSetSocketOption,
(PRSendfileFN)_PR_InvalidInt,
@@ -1156,8 +1109,8 @@ static PRIOMethods socketpollfdMethods = {
(PRTransmitfileFN)_PR_InvalidInt,
(PRGetsocknameFN)_PR_InvalidStatus,
(PRGetpeernameFN)_PR_InvalidStatus,
- (PRGetsockoptFN)_PR_InvalidStatus,
- (PRSetsockoptFN)_PR_InvalidStatus,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
@@ -1183,24 +1136,65 @@ static const PRIOMethods* PR_GetSocketPollFdMethods()
return &socketpollfdMethods;
} /* PR_GetSocketPollFdMethods */
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+PR_EXTERN(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd);
+
+#if defined(_PR_INET6_PROBE)
+
+PR_EXTERN(PRBool) _pr_ipv6_is_present;
+
+PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket()
+{
+PRInt32 osfd;
+
+ osfd = _PR_MD_SOCKET(AF_INET6, SOCK_STREAM, 0);
+ if (osfd != -1) {
+ _PR_MD_CLOSE_SOCKET(osfd);
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+#endif /* _PR_INET6_PROBE */
+
+#endif
PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
{
PRInt32 osfd;
PRFileDesc *fd;
+ PRInt32 tmp_domain = domain;
if (!_pr_initialized) _PR_ImplicitInitialization();
- if (AF_INET != domain
-#if defined(_PR_INET6)
- && AF_INET6 != domain
-#endif
+ if (PR_AF_INET != domain
+ && PR_AF_INET6 != domain
#if defined(XP_UNIX)
- && AF_UNIX != domain
+ && PR_AF_LOCAL != domain
#endif
) {
PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
return NULL;
}
+
+#if defined(_PR_INET6)
+ if (PR_AF_INET6 == domain) {
+#if defined(_PR_INET6_PROBE)
+ if (_pr_ipv6_is_present == PR_FALSE)
+ domain = AF_INET;
+ else
+#endif
+ domain = AF_INET6;
+ }
+#elif defined(_PR_INET6_PROBE)
+ if (PR_AF_INET6 == domain) {
+ if (_pr_ipv6_is_present == PR_FALSE)
+ domain = AF_INET;
+ else
+ domain = AF_INET6;
+ }
+#else
+ if (PR_AF_INET6 == domain)
+ domain = AF_INET;
+#endif /* _PR_INET6 */
osfd = _PR_MD_SOCKET(domain, type, proto);
if (osfd == -1) {
return 0;
@@ -1212,10 +1206,23 @@ PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
/*
* Make the sockets non-blocking
*/
- if (fd != NULL)
+ if (fd != NULL) {
_PR_MD_MAKE_NONBLOCK(fd);
- else
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+ /*
+ * For platforms with no support for IPv6
+ * create layered socket for IPv4-mapped IPv6 addresses
+ */
+ if (PR_AF_INET6 == tmp_domain && PR_AF_INET == domain) {
+ if (PR_FAILURE == _pr_push_ipv6toipv4_layer(fd)) {
+ PR_Close(fd);
+ fd = NULL;
+ }
+ }
+#endif
+ } else
_PR_MD_CLOSE_SOCKET(osfd);
+
return fd;
}
@@ -1223,11 +1230,6 @@ PR_IMPLEMENT(PRFileDesc *) PR_NewTCPSocket(void)
{
PRInt32 domain = AF_INET;
-#if defined(_PR_INET6)
- if (_pr_ipv6_enabled) {
- domain = AF_INET6;
- }
-#endif
return PR_Socket(domain, SOCK_STREAM, 0);
}
@@ -1235,11 +1237,6 @@ PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket(void)
{
PRInt32 domain = AF_INET;
-#if defined(_PR_INET6)
- if (_pr_ipv6_enabled) {
- domain = AF_INET6;
- }
-#endif
return PR_Socket(domain, SOCK_DGRAM, 0);
}
diff --git a/pr/src/linking/prlink.c b/pr/src/linking/prlink.c
index 998e6378..e4d093f1 100644
--- a/pr/src/linking/prlink.c
+++ b/pr/src/linking/prlink.c
@@ -31,7 +31,6 @@
#include <Strings.h>
#include <Aliases.h>
-#include "prlink_mac.h"
#include "macdll.h"
#include "mdmac.h"
#endif
@@ -261,6 +260,7 @@ PR_IMPLEMENT(PRStatus) PR_SetLibraryPath(const char *path)
{
PRStatus rv = PR_SUCCESS;
+ if (!_pr_initialized) _PR_ImplicitInitialization();
PR_EnterMonitor(pr_linker_lock);
PR_FREEIF(_pr_currentLibPath);
if (path) {
@@ -285,6 +285,7 @@ PR_GetLibraryPath()
char *ev;
char *copy = NULL; /* a copy of _pr_currentLibPath */
+ if (!_pr_initialized) _PR_ImplicitInitialization();
PR_EnterMonitor(pr_linker_lock);
if (_pr_currentLibPath != NULL) {
goto exit;
@@ -798,6 +799,7 @@ PR_FindLibrary(const char *name)
{
PRLibrary* result;
+ if (!_pr_initialized) _PR_ImplicitInitialization();
PR_EnterMonitor(pr_linker_lock);
result = pr_UnlockedFindLibrary(name);
PR_ExitMonitor(pr_linker_lock);
@@ -807,17 +809,6 @@ PR_FindLibrary(const char *name)
#ifdef XP_MAC
-PR_IMPLEMENT(PRLibrary*)
-PR_LoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName)
-{
- PRLibSpec libSpec;
-
- libSpec.type = PR_LibSpec_MacNamedFragment;
- libSpec.value.mac_named_fragment.fsspec = fileSpec;
- libSpec.value.mac_named_fragment.name = fragmentName;
- return PR_LoadLibraryWithFlags(libSpec, 0);
-}
-
static PRLibrary*
pr_Mac_LoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName)
{
@@ -875,17 +866,6 @@ unlock:
}
-PR_EXTERN(PRLibrary*)
-PR_LoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragIndex)
-{
- PRLibSpec libSpec;
-
- libSpec.type = PR_LibSpec_MacIndexedFragment;
- libSpec.value.mac_indexed_fragment.fsspec = fileSpec;
- libSpec.value.mac_indexed_fragment.index = fragIndex;
- return PR_LoadLibraryWithFlags(libSpec, 0);
-}
-
static PRLibrary*
pr_Mac_LoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragIndex)
{
@@ -1166,6 +1146,7 @@ PR_FindSymbolAndLibrary(const char *raw_name, PRLibrary* *lib)
#endif
PRLibrary* lm;
+ if (!_pr_initialized) _PR_ImplicitInitialization();
/*
** Mangle the raw symbol name in any way that is platform specific.
*/
diff --git a/pr/src/md/mac/macsocket.h b/pr/src/md/mac/macsocket.h
index 9c4612d2..4c307b55 100644
--- a/pr/src/md/mac/macsocket.h
+++ b/pr/src/md/mac/macsocket.h
@@ -164,8 +164,6 @@ extern int select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfd
#define macsock_shutdown PR_Shutdown
#define macsock_getpeername PR_GetPeerName
#define macsock_getsockname PR_GetSockName
-#define macsock_getsockopt PR_GetSockOpt
-#define macsock_setsockopt PR_SetSockOpt
#define macsock_socketavailable PR_SocketAvailable
#define macsock_send PR_Send
#define macsock_sendto PR_SendTo
diff --git a/pr/src/md/mac/macsockotpt.c b/pr/src/md/mac/macsockotpt.c
index 004bd103..31a123cd 100644
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -243,6 +243,22 @@ static void PrepareForAsyncCompletion(PRThread * thread, PRInt32 osfd)
}
+static void
+WakeUpNotifiedThread(PRThread *thread, OTResult result)
+{
+ _PRCPU * cpu = _PR_MD_CURRENT_CPU();
+
+ if (thread) {
+ thread->md.osErrCode = result;
+ if (_PR_MD_GET_INTSOFF()) {
+ cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
+ thread->md.missedIONotify = PR_TRUE;
+ return;
+ }
+ DoneWaitingOnThisThread(thread);
+ }
+}
+
// Notification routine
// Async callback routine.
// A5 is OK. Cannot allocate memory here
@@ -252,9 +268,9 @@ pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult resul
_MDFileDesc * md = &(secret->md);
EndpointRef endpoint = (EndpointRef)secret->md.osfd;
PRThread * thread = NULL;
- _PRCPU * cpu = _PR_MD_CURRENT_CPU();
OSStatus err;
OTResult resultOT;
+ TDiscon discon;
switch (code)
{
@@ -303,10 +319,28 @@ pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult resul
return;
case T_DISCONNECT: // A disconnect is available
- err = OTRcvDisconnect(endpoint, NULL);
+ discon.udata.len = 0;
+ err = OTRcvDisconnect(endpoint, &discon);
PR_ASSERT(err == kOTNoError);
secret->md.exceptReady = PR_TRUE;
secret->md.connectionOpen = PR_FALSE;
+
+ // wake up waiting threads, if any
+ result = -3199 - discon.reason; // obtain the negative error code
+
+ if ((thread = secret->md.read.thread) != NULL) {
+ secret->md.read.thread = NULL;
+ secret->md.read.cookie = cookie;
+ WakeUpNotifiedThread(thread, result);
+ }
+
+ if ((thread = secret->md.write.thread) != NULL) {
+ secret->md.write.thread = NULL;
+ secret->md.write.cookie = cookie;
+ WakeUpNotifiedThread(thread, result);
+ }
+
+ thread = NULL; // already took care of notification here
break;
case T_ERROR: // obsolete/unused in library
@@ -323,6 +357,11 @@ pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult resul
secret->md.readReady = PR_TRUE; // mark readable (to emulate bsd sockets)
// remember connection is closed, so we can return 0 on read or receive
secret->md.connectionOpen = PR_FALSE;
+
+ thread = secret->md.read.thread;
+ secret->md.read.thread = NULL;
+ secret->md.read.cookie = cookie;
+
break;
case T_GODATA: // Flow control lifted on standard data
@@ -391,16 +430,7 @@ pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult resul
return;
}
- if (thread) {
- thread->md.osErrCode = result;
- if (_PR_MD_GET_INTSOFF()) {
- cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
- thread->md.missedIONotify = PR_TRUE;
- return;
- }
-
- DoneWaitingOnThisThread(thread);
- }
+ WakeUpNotifiedThread(thread, result);
}
@@ -988,7 +1018,7 @@ PRInt32 _MD_socketavailable(PRFileDesc *fd)
err = OTCountDataBytes(endpoint, &bytes);
if ((err == kOTLookErr) || // Not really errors, we just need to do a read,
- (err == kOTNoDataErr)) // or there’s nothing there.
+ (err == kOTNoDataErr)) // or there's nothing there.
err = kOTNoError;
if (err != kOTNoError)
diff --git a/pr/src/md/mac/prcpucfg.h b/pr/src/md/mac/prcpucfg.h
index e14a0cf8..bc203a42 100644
--- a/pr/src/md/mac/prcpucfg.h
+++ b/pr/src/md/mac/prcpucfg.h
@@ -26,6 +26,8 @@
#undef IS_LITTLE_ENDIAN
#define IS_BIG_ENDIAN 1
+#define PR_AF_INET6 30 /* same as AF_INET6 */
+
#define PR_BYTES_PER_BYTE 1L
#define PR_BYTES_PER_SHORT 2L
#define PR_BYTES_PER_INT 4L
diff --git a/pr/src/md/windows/Makefile b/pr/src/md/windows/Makefile
index 78a6527f..0655ba19 100644
--- a/pr/src/md/windows/Makefile
+++ b/pr/src/md/windows/Makefile
@@ -40,6 +40,7 @@ else
ifeq ($(OS_TARGET), WIN95)
CSRCS = \
ntmisc.c \
+ ntsec.c \
ntsem.c \
ntinrval.c \
ntgc.c \
@@ -58,6 +59,7 @@ else
CSRCS = \
ntdllmn.c \
ntmisc.c \
+ ntsec.c \
ntsem.c \
ntinrval.c \
ntgc.c \
diff --git a/pr/src/md/windows/ntio.c b/pr/src/md/windows/ntio.c
index 1b60a380..5326be68 100644
--- a/pr/src/md/windows/ntio.c
+++ b/pr/src/md/windows/ntio.c
@@ -37,6 +37,7 @@
#include "primpl.h"
#include "pprmwait.h"
#include <direct.h>
+#include <mbstring.h>
static HANDLE _pr_completion_port;
static PRThread *_pr_io_completion_thread;
@@ -60,6 +61,24 @@ extern PRUint32 _nt_idleCount;
#define CLOSE_TIMEOUT PR_SecondsToInterval(5)
/*
+ * NSPR-to-NT access right mapping table for files.
+ */
+static DWORD fileAccessTable[] = {
+ FILE_GENERIC_READ,
+ FILE_GENERIC_WRITE,
+ FILE_GENERIC_EXECUTE
+};
+
+/*
+ * NSPR-to-NT access right mapping table for directories.
+ */
+static DWORD dirAccessTable[] = {
+ FILE_GENERIC_READ,
+ FILE_GENERIC_WRITE|FILE_DELETE_CHILD,
+ FILE_GENERIC_EXECUTE
+};
+
+/*
* The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
* We store the value in a PRTime variable for convenience.
* This constant is used by _PR_FileTimeToPRTime().
@@ -76,10 +95,6 @@ PRInt32 IsFileLocal(HANDLE hFile);
static PRInt32 _md_MakeNonblock(HANDLE);
-/* The _nt_use_async flag is used to prevent nspr from using any async io.
- * this is a temporary hack. Don't learn to rely on it.
- */
-static int _nt_use_async = 1;
PRInt32 _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr_in *addr, int *len, PRIntervalTime);
PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, PRIntervalTime);
PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime);
@@ -889,6 +904,8 @@ _PR_MD_INIT_IO()
PR_ASSERT(filetime.prt == _pr_filetime_offset);
}
#endif /* DEBUG */
+
+ _PR_NT_InitSids();
}
/* --- SOCKET IO --------------------------------------------------------- */
@@ -913,11 +930,6 @@ _md_get_recycled_socket()
}
_MD_UNLOCK(&_pr_recycle_lock);
-#ifdef _PR_INET6
- if (_pr_ipv6_enabled) {
- af = AF_INET6;
- }
-#endif
rv = _PR_MD_SOCKET(af, SOCK_STREAM, 0);
if (rv != INVALID_SOCKET && _md_Associate((HANDLE)rv) == 0) {
closesocket(rv);
@@ -1127,7 +1139,7 @@ _PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen,
PRThread *cThread;
struct connect_data_s cd;
- if (!_nt_use_async || fd->secret->nonblocking) {
+ if (fd->secret->nonblocking) {
PRInt32 rv;
fd_set wd;
struct timeval tv, *tvp;
@@ -1294,7 +1306,7 @@ _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
PRUint32 llen, err;
int rv;
- if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+ if (fd->secret->nonblocking || fd->secret->inheritable) {
if (!fd->secret->md.io_model_committed) {
rv = _md_MakeNonblock((HANDLE)osfd);
PR_ASSERT(0 != rv);
@@ -1306,7 +1318,7 @@ _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
* the listening socket.
*/
accept_sock = _nt_nonblock_accept(fd, (struct sockaddr_in *)raddr, rlen, timeout);
- if (_nt_use_async && !fd->secret->nonblocking) {
+ if (!fd->secret->nonblocking) {
u_long zero = 0;
rv = ioctlsocket(accept_sock, FIONBIO, &zero);
@@ -1441,21 +1453,6 @@ _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr,
PRBool isConnected;
PRBool madeCallback = PR_FALSE;
- if (!_nt_use_async) {
- PRFileDesc *nd;
- bytes = _PR_EmulateAcceptRead(sd, &nd, raddr, buf, amount, timeout);
- if (bytes != -1) {
- /*
- * This part is the same as SocketClose(nd), except
- * that we don't close the osfd.
- */
- PR_ASSERT(nd->secret->state == _PR_FILEDESC_OPEN);
- *newSock = nd->secret->md.osfd;
- PR_FreeFileDesc(nd);
- }
- return bytes;
- }
-
if (me->io_suspended) {
PR_SetError(PR_INVALID_STATE_ERROR, 0);
return -1;
@@ -1620,15 +1617,6 @@ _PR_MD_SENDFILE(PRFileDesc *sock, PRSendFileData *sfd,
PRInt32 tflags;
int rv, err;
- if (!_nt_use_async) {
- if (!sock->secret->md.io_model_committed) {
- rv = _md_MakeNonblock((HANDLE)sock->secret->md.osfd);
- PR_ASSERT(0 != rv);
- sock->secret->md.io_model_committed = PR_TRUE;
- }
- return _PR_EmulateSendFile(sock, sfd, flags, timeout);
- }
-
if (me->io_suspended) {
PR_SetError(PR_INVALID_STATE_ERROR, 0);
return -1;
@@ -1735,7 +1723,7 @@ _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
int bytes;
int rv, err;
- if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+ if (fd->secret->nonblocking || fd->secret->inheritable) {
if (!fd->secret->md.io_model_committed) {
rv = _md_MakeNonblock((HANDLE)osfd);
PR_ASSERT(0 != rv);
@@ -1834,7 +1822,7 @@ _PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
int bytes;
int rv, err;
- if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+ if (fd->secret->nonblocking || fd->secret->inheritable) {
if (!fd->secret->md.io_model_committed) {
rv = _md_MakeNonblock((HANDLE)osfd);
PR_ASSERT(0 != rv);
@@ -1932,7 +1920,7 @@ _PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
PR_ASSERT(0 != rv);
fd->secret->md.io_model_committed = PR_TRUE;
}
- if (_nt_use_async && !fd->secret->nonblocking && !fd->secret->inheritable)
+ if (!fd->secret->nonblocking && !fd->secret->inheritable)
return pt_SendTo(osfd, buf, amount, flags, addr, addrlen, timeout);
else
return _nt_nonblock_sendto(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout);
@@ -1950,7 +1938,7 @@ _PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
PR_ASSERT(0 != rv);
fd->secret->md.io_model_committed = PR_TRUE;
}
- if (_nt_use_async && !fd->secret->nonblocking && !fd->secret->inheritable)
+ if (!fd->secret->nonblocking && !fd->secret->inheritable)
return pt_RecvFrom(osfd, buf, amount, flags, addr, addrlen, timeout);
else
return _nt_nonblock_recvfrom(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout);
@@ -1965,7 +1953,7 @@ _PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTi
int sent = 0;
int rv;
- if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+ if (fd->secret->nonblocking || fd->secret->inheritable) {
if (!fd->secret->md.io_model_committed) {
rv = _md_MakeNonblock((HANDLE)osfd);
PR_ASSERT(0 != rv);
@@ -2115,79 +2103,102 @@ _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode)
if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
- if (_nt_use_async)
- {
- if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
- if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
-
- if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
- flags = CREATE_NEW;
- else if (osflags & PR_CREATE_FILE)
- flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
- else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
- else flags = OPEN_EXISTING;
-
-
- flag6 |= FILE_FLAG_OVERLAPPED;
-
- file = CreateFile(name,
- access,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL,
- flags,
- flag6,
- NULL);
- if (file == INVALID_HANDLE_VALUE) {
- _PR_MD_MAP_OPEN_ERROR(GetLastError());
- return -1;
- }
+ if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
+ if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
- if (osflags & PR_APPEND) {
- if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
- _PR_MD_MAP_LSEEK_ERROR(GetLastError());
- CloseHandle(file);
- return -1;
- }
- }
+ if ( osflags & PR_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;
- return (PRInt32)file;
+ 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;
}
- else
- {
-
- if (osflags & PR_RDONLY || osflags & PR_RDWR)
- access |= GENERIC_READ;
- if (osflags & PR_WRONLY || osflags & PR_RDWR)
- access |= GENERIC_WRITE;
-
- if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
- flags = CREATE_NEW;
- else if (osflags & PR_CREATE_FILE) {
- if (osflags & PR_TRUNCATE)
- flags = CREATE_ALWAYS;
- else
- flags = OPEN_ALWAYS;
- } else {
- if (osflags & PR_TRUNCATE)
- flags = TRUNCATE_EXISTING;
- else
- flags = OPEN_EXISTING;
+
+ if (osflags & PR_APPEND) {
+ if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
+ _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+ CloseHandle(file);
+ return -1;
}
+ }
+
+ return (PRInt32)file;
+}
+
+PRInt32
+_PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode)
+{
+ HANDLE file;
+ PRInt32 access = 0;
+ PRInt32 flags = 0;
+ PRInt32 flag6 = 0;
+ SECURITY_ATTRIBUTES sa;
+ LPSECURITY_ATTRIBUTES lpSA = NULL;
+ PSECURITY_DESCRIPTOR pSD = NULL;
+ PACL pACL = NULL;
- 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_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;
+ }
- return (PRInt32)file;
+ if (osflags & PR_APPEND) {
+ if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
+ _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+ CloseHandle(file);
+ return -1;
+ }
}
+
+ return (PRInt32)file;
}
PRInt32
@@ -2196,8 +2207,10 @@ _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
PRInt32 f = fd->secret->md.osfd;
PRUint32 bytes;
int rv, err;
+ LONG hiOffset = 0;
+ LONG loOffset;
- if (_nt_use_async && !fd->secret->md.sync_file_io) {
+ if (!fd->secret->md.sync_file_io) {
PRThread *me = _PR_MD_CURRENT_THREAD();
if (me->io_suspended) {
@@ -2207,7 +2220,8 @@ _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
- me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, 0, FILE_CURRENT);
+ me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT);
+ PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR));
if (fd->secret->inheritable) {
rv = ReadFile((HANDLE)f,
@@ -2216,7 +2230,8 @@ _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
&bytes,
&me->md.overlapped.overlapped);
if (rv != 0) {
- SetFilePointer((HANDLE)f, bytes, 0, FILE_CURRENT);
+ loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+ PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
return bytes;
}
err = GetLastError();
@@ -2224,7 +2239,8 @@ _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
rv = GetOverlappedResult((HANDLE)f,
&me->md.overlapped.overlapped, &bytes, TRUE);
if (rv != 0) {
- SetFilePointer((HANDLE)f, bytes, 0, FILE_CURRENT);
+ loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+ PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
return bytes;
}
err = GetLastError();
@@ -2342,8 +2358,10 @@ _PR_MD_WRITE(PRFileDesc *fd, void *buf, PRInt32 len)
PRInt32 f = fd->secret->md.osfd;
PRInt32 bytes;
int rv, err;
+ LONG hiOffset = 0;
+ LONG loOffset;
- if (_nt_use_async && !fd->secret->md.sync_file_io) {
+ if (!fd->secret->md.sync_file_io) {
PRThread *me = _PR_MD_CURRENT_THREAD();
if (me->io_suspended) {
@@ -2353,7 +2371,8 @@ _PR_MD_WRITE(PRFileDesc *fd, void *buf, PRInt32 len)
memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
- me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, 0, FILE_CURRENT);
+ me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT);
+ PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR));
if (fd->secret->inheritable) {
rv = WriteFile((HANDLE)f,
@@ -2362,7 +2381,8 @@ _PR_MD_WRITE(PRFileDesc *fd, void *buf, PRInt32 len)
&bytes,
&me->md.overlapped.overlapped);
if (rv != 0) {
- SetFilePointer((HANDLE)f, bytes, 0, FILE_CURRENT);
+ loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+ PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
return bytes;
}
err = GetLastError();
@@ -2370,7 +2390,8 @@ _PR_MD_WRITE(PRFileDesc *fd, void *buf, PRInt32 len)
rv = GetOverlappedResult((HANDLE)f,
&me->md.overlapped.overlapped, &bytes, TRUE);
if (rv != 0) {
- SetFilePointer((HANDLE)f, bytes, 0, FILE_CURRENT);
+ loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+ PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
return bytes;
}
err = GetLastError();
@@ -2587,62 +2608,50 @@ PRInt32
_PR_MD_CLOSE(PRInt32 osfd, PRBool socket)
{
PRInt32 rv;
- if (_nt_use_async) {
- PRThread *me = _PR_MD_CURRENT_THREAD();
+ 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 (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;
+ 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);
+ _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);
- }
+ if (fWait)
+ _NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
+ PR_ASSERT(me->io_suspended == PR_FALSE);
+ PR_ASSERT(me->io_pending == PR_FALSE);
+ /*
+ * I/O operation is no longer pending; the thread can now
+ * run on any cpu
+ */
+ _PR_THREAD_LOCK(me);
+ me->md.interrupt_disabled = PR_FALSE;
+ me->md.thr_bound_cpu = NULL;
+ me->io_suspended = PR_FALSE;
+ me->io_pending = PR_FALSE;
+ me->state = _PR_RUNNING;
+ _PR_THREAD_UNLOCK(me);
}
- } else {
- if (socket) {
- rv = closesocket((SOCKET)osfd);
- if (rv == -1)
- _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
- } else {
- rv = CloseHandle((HANDLE)osfd)?0:-1;
- if (rv == -1)
- _PR_MD_MAP_CLOSE_ERROR(GetLastError());
- }
}
return rv;
}
@@ -2661,7 +2670,7 @@ _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
HANDLE_FLAG_INHERIT,
inheritable ? HANDLE_FLAG_INHERIT : 0);
if (0 == rv) {
- PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+ _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
return PR_FAILURE;
}
return PR_SUCCESS;
@@ -2675,12 +2684,12 @@ _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
void FlipSlashes(char *cp, int len)
{
while (--len >= 0) {
- if (cp[0] == '/') {
- cp[0] = PR_DIRECTORY_SEPARATOR;
- }
- cp++;
+ if (cp[0] == '/') {
+ cp[0] = PR_DIRECTORY_SEPARATOR;
+ }
+ cp = _mbsinc(cp);
}
-}
+} /* end FlipSlashes() */
/*
**
@@ -2979,7 +2988,7 @@ _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
* FindFirstFile() expands wildcard characters. So
* we make sure the pathname contains no wildcard.
*/
- if (NULL != strpbrk(fn, "?*")) {
+ if (NULL != _mbspbrk(fn, "?*")) {
PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0);
return -1;
}
@@ -3001,7 +3010,7 @@ _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
* If the pathname does not contain ., \, and /, it cannot be
* a root directory or a pathname that ends in a slash.
*/
- if (NULL == strpbrk(fn, ".\\/")) {
+ if (NULL == _mbspbrk(fn, ".\\/")) {
_PR_MD_MAP_OPENDIR_ERROR(GetLastError());
return -1;
}
@@ -3177,6 +3186,34 @@ _PR_MD_MKDIR(const char *name, PRIntn mode)
}
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)) {
@@ -3668,11 +3705,6 @@ PRInt32 IsFileLocal(HANDLE hFile)
}
#endif /* _NEED_351_FILE_LOCKING_HACK */
-PR_IMPLEMENT(void) PR_NT_UseNonblock()
-{
- _nt_use_async = 0;
-}
-
PR_IMPLEMENT(PRStatus) PR_NT_CancelIo(PRFileDesc *fd)
{
PRThread *me = _PR_MD_CURRENT_THREAD();
diff --git a/pr/src/md/windows/ntsec.c b/pr/src/md/windows/ntsec.c
new file mode 100644
index 00000000..d1c137b4
--- /dev/null
+++ b/pr/src/md/windows/ntsec.c
@@ -0,0 +1,252 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 2000 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#include "primpl.h"
+
+/*
+ * ntsec.c
+ *
+ * Implement the POSIX-style mode bits (access permissions) for
+ * files and other securable objects in Windows NT using Windows
+ * NT's security descriptors with appropriate discretionary
+ * access-control lists.
+ */
+
+/*
+ * The security identifiers (SIDs) for owner, primary group,
+ * and the Everyone (World) group.
+ *
+ * These SIDs are looked up during NSPR initialization and
+ * saved in this global structure (see _PR_NT_InitSids) so
+ * that _PR_NT_MakeSecurityDescriptorACL doesn't need to
+ * look them up every time.
+ */
+static struct {
+ PSID owner;
+ PSID group;
+ PSID everyone;
+} _pr_nt_sids;
+
+/*
+ * Initialize the SIDs for owner, primary group, and the Everyone
+ * group in the _pr_nt_sids structure.
+ *
+ * This function needs to be called by NSPR initialization.
+ */
+void _PR_NT_InitSids(void)
+{
+ SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
+ HANDLE hToken;
+ UCHAR infoBuffer[1024];
+ PTOKEN_OWNER pTokenOwner = (PTOKEN_OWNER) infoBuffer;
+ PTOKEN_PRIMARY_GROUP pTokenPrimaryGroup
+ = (PTOKEN_PRIMARY_GROUP) infoBuffer;
+ DWORD dwLength;
+ BOOL rv;
+
+ /* Create a well-known SID for the Everyone group. */
+ if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,
+ SECURITY_WORLD_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &_pr_nt_sids.everyone)) {
+ /*
+ * On non-NT systems, this function is not implemented,
+ * and neither are the other security functions. There
+ * is no point in going further.
+ */
+ PR_ASSERT(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED);
+ return;
+ }
+
+ /*
+ * Look up and make a copy of the owner and primary group
+ * SIDs in the access token of the calling process.
+ */
+ rv = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
+ PR_ASSERT(rv != 0);
+
+ rv = GetTokenInformation(hToken, TokenOwner, infoBuffer,
+ sizeof(infoBuffer), &dwLength);
+ PR_ASSERT(rv != 0);
+ dwLength = GetLengthSid(pTokenOwner->Owner);
+ _pr_nt_sids.owner = (PSID) PR_Malloc(dwLength);
+ PR_ASSERT(_pr_nt_sids.owner != NULL);
+ rv = CopySid(dwLength, _pr_nt_sids.owner, pTokenOwner->Owner);
+ PR_ASSERT(rv != 0);
+
+ rv = GetTokenInformation(hToken, TokenPrimaryGroup, infoBuffer,
+ sizeof(infoBuffer), &dwLength);
+ PR_ASSERT(rv != 0);
+ dwLength = GetLengthSid(pTokenPrimaryGroup->PrimaryGroup);
+ _pr_nt_sids.group = (PSID) PR_Malloc(dwLength);
+ PR_ASSERT(_pr_nt_sids.group != NULL);
+ rv = CopySid(dwLength, _pr_nt_sids.group,
+ pTokenPrimaryGroup->PrimaryGroup);
+ PR_ASSERT(rv != 0);
+
+ rv = CloseHandle(hToken);
+ PR_ASSERT(rv != 0);
+}
+
+/*
+ * Free the SIDs for owner, primary group, and the Everyone group
+ * in the _pr_nt_sids structure.
+ *
+ * This function needs to be called by NSPR cleanup.
+ */
+void
+_PR_NT_FreeSids(void)
+{
+ if (_pr_nt_sids.owner) {
+ PR_Free(_pr_nt_sids.owner);
+ }
+ if (_pr_nt_sids.group) {
+ PR_Free(_pr_nt_sids.group);
+ }
+ if (_pr_nt_sids.everyone) {
+ FreeSid(_pr_nt_sids.everyone);
+ }
+}
+
+/*
+ * Construct a security descriptor whose discretionary access-control
+ * list implements the specified mode bits. The SIDs for owner, group,
+ * and everyone are obtained from the global _pr_nt_sids structure.
+ * Both the security descriptor and access-control list are returned
+ * and should be freed by a _PR_NT_FreeSecurityDescriptorACL call.
+ *
+ * The accessTable array maps NSPR's read, write, and execute access
+ * rights to the corresponding NT access rights for the securable
+ * object.
+ */
+PRStatus
+_PR_NT_MakeSecurityDescriptorACL(
+ PRIntn mode,
+ DWORD accessTable[],
+ PSECURITY_DESCRIPTOR *resultSD,
+ PACL *resultACL)
+{
+ PSECURITY_DESCRIPTOR pSD = NULL;
+ PACL pACL = NULL;
+ DWORD cbACL; /* size of ACL */
+ DWORD accessMask;
+
+ if (_pr_nt_sids.owner == NULL) {
+ PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+ return PR_FAILURE;
+ }
+
+ pSD = (PSECURITY_DESCRIPTOR) PR_Malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
+ if (pSD == NULL) {
+ _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+ goto failed;
+ }
+ if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
+ _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+ goto failed;
+ }
+ if (!SetSecurityDescriptorOwner(pSD, _pr_nt_sids.owner, FALSE)) {
+ _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+ goto failed;
+ }
+ if (!SetSecurityDescriptorGroup(pSD, _pr_nt_sids.group, FALSE)) {
+ _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+ goto failed;
+ }
+
+ /*
+ * Construct a discretionary access-control list with three
+ * access-control entries, one each for owner, primary group,
+ * and Everyone.
+ */
+
+ cbACL = sizeof(ACL)
+ + 3 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))
+ + GetLengthSid(_pr_nt_sids.owner)
+ + GetLengthSid(_pr_nt_sids.group)
+ + GetLengthSid(_pr_nt_sids.everyone);
+ pACL = (PACL) PR_Malloc(cbACL);
+ if (pACL == NULL) {
+ _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+ goto failed;
+ }
+ if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) {
+ _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+ goto failed;
+ }
+ accessMask = 0;
+ if (mode & 00400) accessMask |= accessTable[0];
+ if (mode & 00200) accessMask |= accessTable[1];
+ if (mode & 00100) accessMask |= accessTable[2];
+ if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
+ _pr_nt_sids.owner)) {
+ _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+ goto failed;
+ }
+ accessMask = 0;
+ if (mode & 00040) accessMask |= accessTable[0];
+ if (mode & 00020) accessMask |= accessTable[1];
+ if (mode & 00010) accessMask |= accessTable[2];
+ if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
+ _pr_nt_sids.group)) {
+ _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+ goto failed;
+ }
+ accessMask = 0;
+ if (mode & 00004) accessMask |= accessTable[0];
+ if (mode & 00002) accessMask |= accessTable[1];
+ if (mode & 00001) accessMask |= accessTable[2];
+ if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
+ _pr_nt_sids.everyone)) {
+ _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+ goto failed;
+ }
+
+ if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) {
+ _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+ goto failed;
+ }
+
+ *resultSD = pSD;
+ *resultACL = pACL;
+ return PR_SUCCESS;
+
+failed:
+ if (pSD) {
+ PR_Free(pSD);
+ }
+ if (pACL) {
+ PR_Free(pACL);
+ }
+ return PR_FAILURE;
+}
+
+/*
+ * Free the specified security descriptor and access-control list
+ * previously created by _PR_NT_MakeSecurityDescriptorACL.
+ */
+void
+_PR_NT_FreeSecurityDescriptorACL(PSECURITY_DESCRIPTOR pSD, PACL pACL)
+{
+ if (pSD) {
+ PR_Free(pSD);
+ }
+ if (pACL) {
+ PR_Free(pACL);
+ }
+}
diff --git a/pr/src/md/windows/ntthread.c b/pr/src/md/windows/ntthread.c
index 37cb2e3a..03153aa3 100644
--- a/pr/src/md/windows/ntthread.c
+++ b/pr/src/md/windows/ntthread.c
@@ -118,6 +118,8 @@ _PR_MD_EARLY_INIT()
void _PR_MD_CLEANUP_BEFORE_EXIT(void)
{
+ _PR_NT_FreeSids();
+
WSACleanup();
if (!_pr_use_static_tls) {
diff --git a/pr/src/md/windows/w32ipcsem.c b/pr/src/md/windows/w32ipcsem.c
index 951b1cf8..f1f71153 100644
--- a/pr/src/md/windows/w32ipcsem.c
+++ b/pr/src/md/windows/w32ipcsem.c
@@ -23,6 +23,22 @@
#include "primpl.h"
+/*
+ * NSPR-to-NT access right mapping table for semaphore objects.
+ *
+ * The SYNCHRONIZE access is required by WaitForSingleObject.
+ * The SEMAPHORE_MODIFY_STATE access is required by ReleaseSemaphore.
+ * The OR of these three access masks must equal SEMAPHORE_ALL_ACCESS.
+ * This is because if a semaphore object with the specified name
+ * exists, CreateSemaphore requests SEMAPHORE_ALL_ACCESS access to
+ * the existing object.
+ */
+static DWORD semAccessTable[] = {
+ STANDARD_RIGHTS_REQUIRED|0x1, /* read (0x1 is "query state") */
+ STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, /* write */
+ 0 /* execute */
+};
+
#ifndef _PR_GLOBAL_THREADS_ONLY
/*
@@ -94,6 +110,10 @@ 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) {
@@ -101,7 +121,17 @@ PRSem *_PR_MD_OPEN_SEMAPHORE(
return NULL;
}
if (flags & PR_SEM_CREATE) {
- sem->sem = CreateSemaphore(NULL, value, 0x7fffffff, osname);
+ if (_PR_NT_MakeSecurityDescriptorACL(mode, semAccessTable,
+ &pSD, &pACL) == PR_SUCCESS) {
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = pSD;
+ sa.bInheritHandle = FALSE;
+ lpSA = &sa;
+ }
+ sem->sem = CreateSemaphore(lpSA, value, 0x7fffffff, osname);
+ if (lpSA != NULL) {
+ _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+ }
if (sem->sem == NULL) {
_PR_MD_MAP_DEFAULT_ERROR(GetLastError());
PR_DELETE(sem);
@@ -114,7 +144,8 @@ PRSem *_PR_MD_OPEN_SEMAPHORE(
return NULL;
}
} else {
- sem->sem = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, osname);
+ sem->sem = OpenSemaphore(
+ SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, FALSE, osname);
if (sem->sem == NULL) {
DWORD err = GetLastError();
diff --git a/pr/src/md/windows/w32shm.c b/pr/src/md/windows/w32shm.c
index 4fb60e93..0efd8a45 100644
--- a/pr/src/md/windows/w32shm.c
+++ b/pr/src/md/windows/w32shm.c
@@ -26,6 +26,20 @@
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,
@@ -38,6 +52,10 @@ extern PRSharedMemory * _MD_OpenSharedMemory(
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 )
@@ -72,23 +90,33 @@ extern PRSharedMemory * _MD_OpenSharedMemory(
shm->ident = _PR_SHM_IDENT;
if (flags & PR_SHM_CREATE ) {
- /* XXX: Not 64bit safe. Fix when WinNT goes 64bit, if ever */
+ /* XXX: Not 64bit safe. Fix when WinNT goes 64bit. */
dwHi = 0;
dwLo = shm->size;
+ if (_PR_NT_MakeSecurityDescriptorACL(mode, filemapAccessTable,
+ &pSD, &pACL) == PR_SUCCESS) {
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = pSD;
+ sa.bInheritHandle = FALSE;
+ lpSA = &sa;
+ }
shm->handle = CreateFileMapping(
(HANDLE)-1 ,
- NULL,
+ lpSA,
flProtect,
dwHi,
dwLo,
shm->ipcname);
+ if (lpSA != NULL) {
+ _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+ }
if ( NULL == shm->handle ) {
PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
( "PR_OpenSharedMemory: CreateFileMapping() failed: %s",
shm->ipcname ));
- PR_SetError( PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS );
+ _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
PR_FREEIF( shm->ipcname )
PR_DELETE( shm );
return(NULL);
@@ -110,7 +138,7 @@ extern PRSharedMemory * _MD_OpenSharedMemory(
}
}
} else {
- shm->handle = OpenFileMapping( FILE_MAP_ALL_ACCESS, TRUE, shm->ipcname );
+ shm->handle = OpenFileMapping( FILE_MAP_WRITE, TRUE, shm->ipcname );
if ( NULL == shm->handle ) {
_PR_MD_MAP_DEFAULT_ERROR( GetLastError());
PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
diff --git a/pr/src/md/windows/w95io.c b/pr/src/md/windows/w95io.c
index 6e969a98..d80736fe 100644
--- a/pr/src/md/windows/w95io.c
+++ b/pr/src/md/windows/w95io.c
@@ -24,10 +24,30 @@
#include "primpl.h"
#include <direct.h>
+#include <mbstring.h>
+
struct _MDLock _pr_ioq_lock;
/*
+ * NSPR-to-NT access right mapping table for files.
+ */
+static DWORD fileAccessTable[] = {
+ FILE_GENERIC_READ,
+ FILE_GENERIC_WRITE,
+ FILE_GENERIC_EXECUTE
+};
+
+/*
+ * NSPR-to-NT access right mapping table for directories.
+ */
+static DWORD dirAccessTable[] = {
+ FILE_GENERIC_READ,
+ FILE_GENERIC_WRITE|FILE_DELETE_CHILD,
+ FILE_GENERIC_EXECUTE
+};
+
+/*
* The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
* We store the value in a PRTime variable for convenience.
* This constant is used by _PR_FileTimeToPRTime().
@@ -72,6 +92,8 @@ _PR_MD_INIT_IO()
PR_ASSERT(filetime.prt == _pr_filetime_offset);
}
#endif /* DEBUG */
+
+ _PR_NT_InitSids();
}
PRStatus
@@ -182,6 +204,67 @@ _PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
}
PRInt32
+_PR_MD_OPEN_FILE(const char *name, PRIntn osflags, int mode)
+{
+ HANDLE file;
+ PRInt32 access = 0;
+ PRInt32 flags = 0;
+ PRInt32 flag6 = 0;
+ SECURITY_ATTRIBUTES sa;
+ LPSECURITY_ATTRIBUTES lpSA = NULL;
+ PSECURITY_DESCRIPTOR pSD = NULL;
+ PACL pACL = NULL;
+
+ if (osflags & PR_CREATE_FILE) {
+ if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable,
+ &pSD, &pACL) == PR_SUCCESS) {
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = pSD;
+ sa.bInheritHandle = FALSE;
+ lpSA = &sa;
+ }
+ }
+
+ if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
+
+ if (osflags & PR_RDONLY || osflags & PR_RDWR)
+ access |= GENERIC_READ;
+ if (osflags & PR_WRONLY || osflags & PR_RDWR)
+ access |= GENERIC_WRITE;
+
+ if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+ flags = CREATE_NEW;
+ else if (osflags & PR_CREATE_FILE) {
+ if (osflags & PR_TRUNCATE)
+ flags = CREATE_ALWAYS;
+ else
+ flags = OPEN_ALWAYS;
+ } else {
+ if (osflags & PR_TRUNCATE)
+ flags = TRUNCATE_EXISTING;
+ else
+ flags = OPEN_EXISTING;
+ }
+
+ file = CreateFile(name,
+ access,
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ lpSA,
+ flags,
+ flag6,
+ NULL);
+ if (lpSA != NULL) {
+ _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+ }
+ if (file == INVALID_HANDLE_VALUE) {
+ _PR_MD_MAP_OPEN_ERROR(GetLastError());
+ return -1;
+ }
+
+ return (PRInt32)file;
+}
+
+PRInt32
_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
{
PRUint32 bytes;
@@ -353,12 +436,13 @@ _MD_CloseFile(PRInt32 osfd)
void FlipSlashes(char *cp, int len)
{
while (--len >= 0) {
- if (cp[0] == '/') {
- cp[0] = PR_DIRECTORY_SEPARATOR;
- }
- cp++;
+ if (cp[0] == '/') {
+ cp[0] = PR_DIRECTORY_SEPARATOR;
+ }
+ cp = _mbsinc(cp);
}
-}
+} /* end FlipSlashes() */
+
/*
**
@@ -661,7 +745,7 @@ _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
* FindFirstFile() expands wildcard characters. So
* we make sure the pathname contains no wildcard.
*/
- if (NULL != strpbrk(fn, "?*")) {
+ if (NULL != _mbspbrk(fn, "?*")) {
PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0);
return -1;
}
@@ -683,7 +767,7 @@ _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
* If the pathname does not contain ., \, and /, it cannot be
* a root directory or a pathname that ends in a slash.
*/
- if (NULL == strpbrk(fn, ".\\/")) {
+ if (NULL == _mbspbrk(fn, ".\\/")) {
_PR_MD_MAP_OPENDIR_ERROR(GetLastError());
return -1;
}
@@ -866,6 +950,34 @@ _PR_MD_MKDIR(const char *name, PRIntn mode)
}
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)) {
diff --git a/pr/src/md/windows/w95thred.c b/pr/src/md/windows/w95thred.c
index 69ab1cd9..2625ceea 100644
--- a/pr/src/md/windows/w95thred.c
+++ b/pr/src/md/windows/w95thred.c
@@ -48,6 +48,8 @@ _PR_MD_EARLY_INIT()
void _PR_MD_CLEANUP_BEFORE_EXIT(void)
{
+ _PR_NT_FreeSids();
+
WSACleanup();
#ifndef _PR_USE_STATIC_TLS
diff --git a/pr/src/md/windows/win32_errors.c b/pr/src/md/windows/win32_errors.c
index 0e73c560..99427933 100644
--- a/pr/src/md/windows/win32_errors.c
+++ b/pr/src/md/windows/win32_errors.c
@@ -142,6 +142,9 @@ void _MD_win32_map_default_error(PRInt32 err)
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;
diff --git a/pr/src/misc/prerr.c b/pr/src/misc/prerr.c
index 7b320be7..3f366760 100644
--- a/pr/src/misc/prerr.c
+++ b/pr/src/misc/prerr.c
@@ -88,7 +88,7 @@ static const struct PRErrorMessage text[] = {
{"PR_END_OF_FILE_ERROR", "Encountered end of file"},
{"PR_FILE_SEEK_ERROR", "Seek error"},
{"PR_FILE_IS_BUSY_ERROR", "The file is busy"},
- {"PR_RESERVED_ERROR_5935", "Reserved Error Code -5935"},
+ {"PR_OPERATION_ABORTED_ERROR", "The I/O operation was aborted"},
{"PR_IN_PROGRESS_ERROR", "Operation is still in progress (probably a non-blocking connect)"},
{"PR_ALREADY_INITIATED_ERROR", "Operation has already been initiated (probably a non-blocking connect)"},
{"PR_GROUP_EMPTY_ERROR", "The wait group is empty"},
diff --git a/pr/src/misc/prerr.et b/pr/src/misc/prerr.et
index 2f0a6f02..c04440f0 100644
--- a/pr/src/misc/prerr.et
+++ b/pr/src/misc/prerr.et
@@ -99,7 +99,7 @@ ec PR_NO_MORE_FILES_ERROR, "No more entries in the directory"
ec PR_END_OF_FILE_ERROR, "Encountered end of file"
ec PR_FILE_SEEK_ERROR, "Seek error"
ec PR_FILE_IS_BUSY_ERROR, "The file is busy"
-ec PR_RESERVED_ERROR_5935, "Reserved Error Code -5935"
+ec PR_OPERATION_ABORTED_ERROR, "The I/O operation was aborted"
ec PR_IN_PROGRESS_ERROR,
"Operation is still in progress (probably a non-blocking connect)"
ec PR_ALREADY_INITIATED_ERROR,
diff --git a/pr/src/misc/prerr.properties b/pr/src/misc/prerr.properties
index 07d58f08..5987967a 100644
--- a/pr/src/misc/prerr.properties
+++ b/pr/src/misc/prerr.properties
@@ -82,7 +82,7 @@ PR_NO_MORE_FILES_ERROR=No more entries in the directory
PR_END_OF_FILE_ERROR=Encountered end of file
PR_FILE_SEEK_ERROR=Seek error
PR_FILE_IS_BUSY_ERROR=The file is busy
-PR_RESERVED_ERROR_5935=Reserved Error Code -5935
+PR_OPERATION_ABORTED_ERROR=The I/O operation was aborted
PR_IN_PROGRESS_ERROR=Operation is still in progress (probably a non-blocking connect)
PR_ALREADY_INITIATED_ERROR=Operation has already been initiated (probably a non-blocking connect)
PR_GROUP_EMPTY_ERROR=The wait group is empty
diff --git a/pr/src/misc/prerror.c b/pr/src/misc/prerror.c
index ed46c1ba..40925696 100644
--- a/pr/src/misc/prerror.c
+++ b/pr/src/misc/prerror.c
@@ -33,12 +33,6 @@ PR_IMPLEMENT(PRInt32) PR_GetOSError()
return thread->osErrorCode;
}
-PR_IMPLEMENT(const char*) PR_GetErrorString()
-{
- PRThread *thread = PR_GetCurrentThread();
- return thread->errorString;
-}
-
PR_IMPLEMENT(void) PR_SetError(PRErrorCode code, PRInt32 osErr)
{
PRThread *thread = PR_GetCurrentThread();
diff --git a/pr/src/misc/prinit.c b/pr/src/misc/prinit.c
index 57fb1c9a..3cdefe35 100644
--- a/pr/src/misc/prinit.c
+++ b/pr/src/misc/prinit.c
@@ -78,11 +78,11 @@ PR_IMPLEMENT(PRBool) PR_VersionCheck(const char *importedVersion)
/*
** This is the secret handshake algorithm.
**
- ** This release (3.1) is backward compatible with
- ** all the previous releases ("2.1 19980529", "3.0",
- ** "3.0.x"). It is not compatible with future
- ** releases or patches. So this release has a
- ** simple version compatibility check algorithm.
+ ** This release has a simple version compatibility
+ ** check algorithm. This release is not backward
+ ** compatible with previous major releases. It is
+ ** not compatible with future major, minor, or
+ ** patch releases.
*/
int vmajor = 0, vminor = 0, vpatch = 0;
const char *ptr = importedVersion;
@@ -106,7 +106,7 @@ PR_IMPLEMENT(PRBool) PR_VersionCheck(const char *importedVersion)
}
}
- if (vmajor > PR_VMAJOR) {
+ if (vmajor != PR_VMAJOR) {
return PR_FALSE;
}
if (vmajor == PR_VMAJOR && vminor > PR_VMINOR) {
@@ -144,6 +144,10 @@ static void _pr_SetNativeThreadsOnlyMode(void)
}
#endif
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+extern PRStatus _pr_init_ipv6();
+#endif
+
static void _PR_InitStuff(void)
{
@@ -220,6 +224,10 @@ static void _PR_InitStuff(void)
nspr_InitializePRErrorTable();
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+ _pr_init_ipv6();
+#endif
+
_PR_MD_FINAL_INIT();
}
diff --git a/pr/src/misc/prnetdb.c b/pr/src/misc/prnetdb.c
index f3e65ff2..a8aa7d10 100644
--- a/pr/src/misc/prnetdb.c
+++ b/pr/src/misc/prnetdb.c
@@ -95,13 +95,54 @@ static sigset_t timer_set;
PRLock* _getproto_lock = NULL;
#endif
-#if defined(_PR_INET6)
-PRBool _pr_ipv6_enabled = PR_FALSE;
-#if defined(AIX)
-const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
-const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
-#endif /* AIX */
-#endif /* _PR_INET6 */
+#if defined(_PR_INET6_PROBE)
+PR_EXTERN(PRBool) _pr_ipv6_is_present;
+#endif
+
+#define _PR_IN6_IS_ADDR_UNSPECIFIED(a) \
+ (((a)->pr_s6_addr32[0] == 0) && \
+ ((a)->pr_s6_addr32[1] == 0) && \
+ ((a)->pr_s6_addr32[2] == 0) && \
+ ((a)->pr_s6_addr32[3] == 0))
+
+#define _PR_IN6_IS_ADDR_LOOPBACK(a) \
+ (((a)->pr_s6_addr32[0] == 0) && \
+ ((a)->pr_s6_addr32[1] == 0) && \
+ ((a)->pr_s6_addr32[2] == 0) && \
+ ((a)->pr_s6_addr[12] == 0) && \
+ ((a)->pr_s6_addr[13] == 0) && \
+ ((a)->pr_s6_addr[14] == 0) && \
+ ((a)->pr_s6_addr[15] == 0x1U))
+
+const PRIPv6Addr _pr_in6addr_any = { 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0 };
+
+const PRIPv6Addr _pr_in6addr_loopback = { 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0x1U };
+/*
+ * The values at bytes 10 and 11 are compared using pointers to
+ * 8-bit fields, and not 32-bit fields, to make the comparison work on
+ * both big-endian and little-endian systems
+ */
+
+#define _PR_IN6_IS_ADDR_V4MAPPED(a) \
+ (((a)->pr_s6_addr32[0] == 0) && \
+ ((a)->pr_s6_addr32[1] == 0) && \
+ ((a)->pr_s6_addr[8] == 0) && \
+ ((a)->pr_s6_addr[9] == 0) && \
+ ((a)->pr_s6_addr[10] == 0xff) && \
+ ((a)->pr_s6_addr[11] == 0xff))
+
+#define _PR_IN6_IS_ADDR_V4COMPAT(a) \
+ (((a)->pr_s6_addr32[0] == 0) && \
+ ((a)->pr_s6_addr32[1] == 0) && \
+ ((a)->pr_s6_addr32[2] == 0))
+
+#define _PR_IN6_V4MAPPED_TO_IPADDR(a) ((a)->pr_s6_addr32[3])
void _PR_InitNet(void)
{
@@ -122,31 +163,6 @@ void _PR_InitNet(void)
#if !defined(_PR_HAVE_GETPROTO_R)
_getproto_lock = PR_NewLock();
#endif
-
-}
-
-PR_IMPLEMENT(PRStatus) PR_SetIPv6Enable(PRBool itIs)
-{
-#if defined(XP_MAC)
-#pragma unused (itIs)
-#endif
-
-#if defined(_PR_INET6)
- _pr_ipv6_enabled = itIs;
- return PR_SUCCESS;
-#else /* defined(_PR_INET6) */
- PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, 0);
- return PR_FAILURE;
-#endif /* defined(_PR_INET6) */
-} /* PR_SetIPv6Enable */
-
-PR_IMPLEMENT(PRStatus) PR_GetHostName(char *name, PRUint32 namelen)
-{
-#if defined(DEBUG)
- static PRBool warn = PR_TRUE;
- if (warn) warn = _PR_Obsolete("PR_GetHostName()", "PR_GetSystemInfo()");
-#endif
- return PR_GetSystemInfo(PR_SI_HOSTNAME, name, namelen);
}
/*
@@ -174,8 +190,6 @@ static char *Alloc(PRIntn amount, char **bufp, PRIntn *buflenp, PRIntn align)
return buf;
}
-#if defined(_PR_INET6)
-
typedef enum _PRIPAddrConversion {
_PRIPAddrNoConversion,
_PRIPAddrIPv4Mapped,
@@ -190,7 +204,7 @@ static void MakeIPv4MappedAddr(const char *v4, char *v6)
memset(v6, 0, 10);
memset(v6 + 10, 0xff, 2);
memcpy(v6 + 12, v4, 4);
- PR_ASSERT(IN6_IS_ADDR_V4MAPPED((struct in6_addr *) v6));
+ PR_ASSERT(_PR_IN6_IS_ADDR_V4MAPPED(((PRIPv6Addr *) v6)));
}
/*
@@ -200,47 +214,42 @@ static void MakeIPv4CompatAddr(const char *v4, char *v6)
{
memset(v6, 0, 12);
memcpy(v6 + 12, v4, 4);
- PR_ASSERT(IN6_IS_ADDR_V4COMPAT((struct in6_addr *) v6));
+ PR_ASSERT(_PR_IN6_IS_ADDR_V4COMPAT(((PRIPv6Addr *) v6)));
}
-#endif /* _PR_INET6 */
-
/*
** Copy a hostent, and all of the memory that it refers to into
** (hopefully) stacked buffers.
*/
static PRStatus CopyHostent(
struct hostent *from,
- char *buf,
- PRIntn bufsize,
-#if defined(_PR_INET6)
+ char **buf,
+ PRIntn *bufsize,
_PRIPAddrConversion conversion,
-#endif
PRHostEnt *to)
{
PRIntn len, na;
char **ap;
- /* Do the easy stuff */
-#if defined(_PR_INET6)
if (conversion != _PRIPAddrNoConversion
&& from->h_addrtype == AF_INET) {
PR_ASSERT(from->h_length == 4);
- to->h_addrtype = AF_INET6;
+ to->h_addrtype = PR_AF_INET6;
to->h_length = 16;
} else {
- to->h_addrtype = from->h_addrtype;
+#if defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+ if (AF_INET6 == from->h_addrtype)
+ to->h_addrtype = PR_AF_INET6;
+ else
+#endif
+ to->h_addrtype = from->h_addrtype;
to->h_length = from->h_length;
}
-#else
- to->h_addrtype = from->h_addrtype;
- to->h_length = from->h_length;
-#endif
/* Copy the official name */
if (!from->h_name) return PR_FAILURE;
len = strlen(from->h_name) + 1;
- to->h_name = Alloc(len, &buf, &bufsize, 0);
+ to->h_name = Alloc(len, buf, bufsize, 0);
if (!to->h_name) return PR_FAILURE;
memcpy(to->h_name, from->h_name, len);
@@ -251,7 +260,7 @@ static PRStatus CopyHostent(
for (na = 1, ap = from->h_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */
}
to->h_aliases = (char**)Alloc(
- na * sizeof(char*), &buf, &bufsize, sizeof(char**));
+ na * sizeof(char*), buf, bufsize, sizeof(char**));
if (!to->h_aliases) return PR_FAILURE;
/* Copy the aliases, one at a time */
@@ -260,7 +269,7 @@ static PRStatus CopyHostent(
} else {
for (na = 0, ap = from->h_aliases; *ap != 0; na++, ap++) {
len = strlen(*ap) + 1;
- to->h_aliases[na] = Alloc(len, &buf, &bufsize, 0);
+ to->h_aliases[na] = Alloc(len, buf, bufsize, 0);
if (!to->h_aliases[na]) return PR_FAILURE;
memcpy(to->h_aliases[na], *ap, len);
}
@@ -270,14 +279,13 @@ static PRStatus CopyHostent(
/* Count the addresses, then allocate storage for the pointers */
for (na = 1, ap = from->h_addr_list; *ap != 0; na++, ap++){;} /* nothing to execute */
to->h_addr_list = (char**)Alloc(
- na * sizeof(char*), &buf, &bufsize, sizeof(char**));
+ na * sizeof(char*), buf, bufsize, sizeof(char**));
if (!to->h_addr_list) return PR_FAILURE;
/* Copy the addresses, one at a time */
for (na = 0, ap = from->h_addr_list; *ap != 0; na++, ap++) {
- to->h_addr_list[na] = Alloc(to->h_length, &buf, &bufsize, 0);
+ to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0);
if (!to->h_addr_list[na]) return PR_FAILURE;
-#if defined(_PR_INET6)
if (conversion != _PRIPAddrNoConversion
&& from->h_addrtype == AF_INET) {
if (conversion == _PRIPAddrIPv4Mapped) {
@@ -289,9 +297,6 @@ static PRStatus CopyHostent(
} else {
memcpy(to->h_addr_list[na], *ap, to->h_length);
}
-#else
- memcpy(to->h_addr_list[na], *ap, to->h_length);
-#endif
}
to->h_addr_list[na] = 0;
return PR_SUCCESS;
@@ -345,9 +350,6 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByName(
#ifdef XP_UNIX
sigset_t oldset;
#endif
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
- int error_num;
-#endif
if (!_pr_initialized) _PR_ImplicitInitialization();
@@ -356,60 +358,22 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByName(
#endif
LOCK_DNS();
-#ifdef _PR_INET6
- if (_pr_ipv6_enabled)
- {
-#ifdef _PR_HAVE_GETHOSTBYNAME2
- h = gethostbyname2(name, AF_INET6);
- if (NULL == h)
- {
- h = gethostbyname2(name, AF_INET);
- }
-#elif defined(_PR_HAVE_GETIPNODEBYNAME)
- h = getipnodebyname(name, AF_INET6, AI_DEFAULT, &error_num);
-#else
-#error "Unknown name-to-address translation function"
-#endif
- }
- else
- {
-#ifdef XP_OS2_VACPP
- h = gethostbyname((char *)name);
-#else
- h = gethostbyname(name);
-#endif
- }
-#else
#ifdef XP_OS2_VACPP
h = gethostbyname((char *)name);
#else
h = gethostbyname(name);
#endif
-#endif /* _PR_INET6 */
if (NULL == h)
{
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
- PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
-#else
PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
-#endif
}
else
{
-#if defined(_PR_INET6)
_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
-
- if (_pr_ipv6_enabled) conversion = _PRIPAddrIPv4Mapped;
- rv = CopyHostent(h, buf, bufsize, conversion, hp);
-#else
- rv = CopyHostent(h, buf, bufsize, hp);
-#endif
+ rv = CopyHostent(h, &buf, &bufsize, conversion, hp);
if (PR_SUCCESS != rv)
PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
- freehostent(h);
-#endif
}
UNLOCK_DNS();
#ifdef XP_UNIX
@@ -418,40 +382,40 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByName(
return rv;
}
+#if defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+typedef struct hostent * (*_pr_getipnodebyname_t)(const char *, int,
+ int, int *);
+typedef struct hostent * (*_pr_getipnodebyaddr_t)(const void *, size_t,
+ int, int *);
+typedef void (*_pr_freehostent_t)(struct hostent *);
+extern void * _pr_getipnodebyname_fp;
+extern void * _pr_getipnodebyaddr_fp;
+extern void * _pr_freehostent_fp;
+#endif
+
PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
const char *name, PRUint16 af, PRIntn flags,
char *buf, PRIntn bufsize, PRHostEnt *hp)
{
- struct hostent *h;
+ struct hostent *h = 0;
PRStatus rv = PR_FAILURE;
#ifdef XP_UNIX
sigset_t oldset;
#endif
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
+#if defined(_PR_HAVE_GETIPNODEBYNAME)
+ PRUint16 md_af = af;
int error_num;
+ int tmp_flags = 0;
+#endif
+#if defined(_PR_HAVE_GETHOSTBYNAME2)
+ PRBool did_af_inet = PR_FALSE;
+ char **new_addr_list;
#endif
if (!_pr_initialized) _PR_ImplicitInitialization();
-#if defined(_PR_INET6)
- PR_ASSERT(af == AF_INET || af == AF_INET6);
- if (af != AF_INET && af != AF_INET6) {
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- return PR_FAILURE;
- }
-#else
- PR_ASSERT(af == AF_INET);
- if (af != AF_INET) {
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- return PR_FAILURE;
- }
-#endif
-
- /*
- * Flags other than PR_AI_DEFAULT are not yet supported.
- */
- PR_ASSERT(flags == PR_AI_DEFAULT);
- if (flags != PR_AI_DEFAULT) {
+ PR_ASSERT(af == PR_AF_INET || af == PR_AF_INET6);
+ if (af != PR_AF_INET && af != PR_AF_INET6) {
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return PR_FAILURE;
}
@@ -461,25 +425,48 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
#endif
LOCK_DNS();
+#if defined(_PR_HAVE_GETIPNODEBYNAME)
+ if (flags & PR_AI_V4MAPPED)
+ tmp_flags |= AI_V4MAPPED;
+ if (flags & PR_AI_ADDRCONFIG)
+ tmp_flags |= AI_ADDRCONFIG;
+ if (flags & PR_AI_ALL)
+ tmp_flags |= AI_ALL;
+ if (af == PR_AF_INET6)
+ md_af = AF_INET6;
+ else
+ md_af = af;
+#endif
+
#ifdef _PR_INET6
#ifdef _PR_HAVE_GETHOSTBYNAME2
- if (af == AF_INET6)
+ if (af == PR_AF_INET6)
{
- h = gethostbyname2(name, af);
- if (NULL == h)
+#ifdef _PR_INET6_PROBE
+ if (_pr_ipv6_is_present == PR_TRUE)
+#endif
+ h = gethostbyname2(name, AF_INET6);
+ if ((NULL == h) && (flags & PR_AI_V4MAPPED))
{
+ did_af_inet = PR_TRUE;
h = gethostbyname2(name, AF_INET);
}
}
else
{
+ did_af_inet = PR_TRUE;
h = gethostbyname2(name, af);
}
#elif defined(_PR_HAVE_GETIPNODEBYNAME)
- h = getipnodebyname(name, af, AI_DEFAULT, &error_num);
+ h = getipnodebyname(name, md_af, tmp_flags, &error_num);
#else
#error "Unknown name-to-address translation function"
-#endif
+#endif /* _PR_HAVE_GETHOSTBYNAME2 */
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+ if (_pr_ipv6_is_present == PR_TRUE)
+ h = (*((_pr_getipnodebyname_t)_pr_getipnodebyname_fp))(name, md_af, tmp_flags, &error_num);
+ else
+ h = gethostbyname(name);
#else /* _PR_INET6 */
#ifdef XP_OS2_VACPP
h = gethostbyname((char *)name);
@@ -492,26 +479,62 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
{
#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+ if (_pr_ipv6_is_present == PR_TRUE)
+ PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+ else
+ PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
#else
PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
#endif
}
else
{
-#if defined(_PR_INET6)
_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
- if (af == AF_INET6) conversion = _PRIPAddrIPv4Mapped;
- rv = CopyHostent(h, buf, bufsize, conversion, hp);
-#else
- rv = CopyHostent(h, buf, bufsize, hp);
-#endif
+ if (af == PR_AF_INET6) conversion = _PRIPAddrIPv4Mapped;
+ rv = CopyHostent(h, &buf, &bufsize, conversion, hp);
if (PR_SUCCESS != rv)
PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
freehostent(h);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+ if (_pr_ipv6_is_present == PR_TRUE)
+ (*((_pr_freehostent_t)_pr_freehostent_fp))(h);
+#endif
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+ if ((flags & PR_AI_V4MAPPED) && (flags & (PR_AI_ALL|PR_AI_ADDRCONFIG))
+ && !did_af_inet && (h = gethostbyname2(name, AF_INET)) != 0) {
+ /* Append the V4 addresses to the end of the list */
+ PRIntn na, na_old;
+ char **ap;
+
+ /* Count the addresses, then grow storage for the pointers */
+ for (na_old = 0, ap = hp->h_addr_list; *ap != 0; na_old++, ap++)
+ {;} /* nothing to execute */
+ for (na = na_old + 1, ap = h->h_addr_list; *ap != 0; na++, ap++)
+ {;} /* nothing to execute */
+ new_addr_list = (char**)Alloc(
+ na * sizeof(char*), &buf, &bufsize, sizeof(char**));
+ if (!new_addr_list) return PR_FAILURE;
+
+ /* Copy the V6 addresses, one at a time */
+ for (na = 0, ap = hp->h_addr_list; *ap != 0; na++, ap++) {
+ new_addr_list[na] = hp->h_addr_list[na];
+ }
+ hp->h_addr_list = new_addr_list;
+
+ /* Copy the V4 addresses, one at a time */
+ for (ap = h->h_addr_list; *ap != 0; na++, ap++) {
+ hp->h_addr_list[na] = Alloc(hp->h_length, &buf, &bufsize, 0);
+ if (!hp->h_addr_list[na]) return PR_FAILURE;
+ MakeIPv4MappedAddr(*ap, hp->h_addr_list[na]);
+ }
+ hp->h_addr_list[na] = 0;
+ }
#endif
}
+
UNLOCK_DNS();
#ifdef XP_UNIX
ENABLECLOCK(&oldset);
@@ -525,11 +548,13 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr(
struct hostent *h;
PRStatus rv = PR_FAILURE;
const void *addr;
+ PRUint32 tmp_ip;
int addrlen;
+ PRInt32 af;
#ifdef XP_UNIX
sigset_t oldset;
#endif
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
+#if defined(_PR_HAVE_GETIPNODEBYADDR)
int error_num;
#endif
@@ -539,56 +564,101 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr(
DISABLECLOCK(&oldset);
#endif
LOCK_DNS();
-#if defined(_PR_INET6)
- if (hostaddr->raw.family == AF_INET6)
+ if (hostaddr->raw.family == PR_AF_INET6)
{
- addr = &hostaddr->ipv6.ip;
- addrlen = sizeof(hostaddr->ipv6.ip);
+#if defined(_PR_INET6_PROBE)
+ if (_pr_ipv6_is_present == PR_TRUE)
+ af = AF_INET6;
+ else
+ af = AF_INET;
+#elif defined(_PR_INET6)
+ af = AF_INET6;
+#else
+ af = AF_INET;
+#endif
}
else
-#endif /* defined(_PR_INET6) */
{
PR_ASSERT(hostaddr->raw.family == AF_INET);
+ af = AF_INET;
+ }
+ if (hostaddr->raw.family == PR_AF_INET6) {
+#if defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+ if (af == AF_INET6) {
+ addr = &hostaddr->ipv6.ip;
+ addrlen = sizeof(hostaddr->ipv6.ip);
+ }
+ else
+#endif
+ {
+ PR_ASSERT(af == AF_INET);
+ if (!_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return rv;
+ }
+ tmp_ip = _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)
+ &hostaddr->ipv6.ip);
+ addr = &tmp_ip;
+ addrlen = sizeof(tmp_ip);
+ }
+ } else {
+ PR_ASSERT(hostaddr->raw.family == AF_INET);
+ PR_ASSERT(af == AF_INET);
addr = &hostaddr->inet.ip;
addrlen = sizeof(hostaddr->inet.ip);
}
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
- h = getipnodebyaddr(addr, addrlen, hostaddr->raw.family, &error_num);
-#else
+
+#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6)
+ h = getipnodebyaddr(addr, addrlen, af, &error_num);
+#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE)
+ if (_pr_ipv6_is_present == PR_TRUE)
+ h = (*((_pr_getipnodebyaddr_t)_pr_getipnodebyaddr_fp))(addr, addrlen,
+ af, &error_num);
+ else
+ h = gethostbyaddr(addr, addrlen, af);
+#else /* _PR_HAVE_GETIPNODEBYADDR */
#ifdef XP_OS2_VACPP
- h = gethostbyaddr((char *)addr, addrlen, hostaddr->raw.family);
+ h = gethostbyaddr((char *)addr, addrlen, af);
#else
- h = gethostbyaddr(addr, addrlen, hostaddr->raw.family);
+ h = gethostbyaddr(addr, addrlen, af);
#endif
-#endif /* _PR_INET6 && _PR_HAVE_GETIPNODEBYADDR */
+#endif /* _PR_HAVE_GETIPNODEBYADDR */
if (NULL == h)
{
#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR)
+ if (_pr_ipv6_is_present == PR_TRUE)
+ PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+ else
+ PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
#else
PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
#endif
}
else
{
-#if defined(_PR_INET6)
_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
- if (hostaddr->raw.family == AF_INET6) {
- if (IN6_IS_ADDR_V4MAPPED((struct in6_addr*)addr)) {
- conversion = _PRIPAddrIPv4Mapped;
- } else if (IN6_IS_ADDR_V4COMPAT((struct in6_addr*)addr)) {
- conversion = _PRIPAddrIPv4Compat;
+ if (hostaddr->raw.family == PR_AF_INET6) {
+ if (af == AF_INET) {
+ if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr*)
+ &hostaddr->ipv6.ip)) {
+ conversion = _PRIPAddrIPv4Mapped;
+ } else if (_PR_IN6_IS_ADDR_V4COMPAT((PRIPv6Addr *)
+ &hostaddr->ipv6.ip)) {
+ conversion = _PRIPAddrIPv4Compat;
+ }
}
}
- rv = CopyHostent(h, buf, bufsize, conversion, hostentry);
-#else
- rv = CopyHostent(h, buf, bufsize, hostentry);
-#endif
+ rv = CopyHostent(h, &buf, &bufsize, conversion, hostentry);
if (PR_SUCCESS != rv) {
PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
}
#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
freehostent(h);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR)
+ if (_pr_ipv6_is_present == PR_TRUE)
+ (*((_pr_freehostent_t)_pr_freehostent_fp))(h);
#endif
}
UNLOCK_DNS();
@@ -807,9 +877,11 @@ PR_IMPLEMENT(PRUintn) PR_NetAddrSize(const PRNetAddr* addr)
*/
if (AF_INET == addr->raw.family)
addrsize = sizeof(addr->inet);
+ else if (PR_AF_INET6 == addr->raw.family)
#if defined(_PR_INET6)
- else if (AF_INET6 == addr->raw.family)
addrsize = sizeof(struct sockaddr_in6);
+#else
+ addrsize = sizeof(addr->ipv6);
#endif
#if defined(XP_UNIX)
else if (AF_UNIX == addr->raw.family)
@@ -829,14 +901,14 @@ PR_IMPLEMENT(PRIntn) PR_EnumerateHostEnt(
else
{
address->raw.family = hostEnt->h_addrtype;
-#if defined(_PR_INET6)
- if (AF_INET6 == hostEnt->h_addrtype)
+ if (PR_AF_INET6 == hostEnt->h_addrtype)
{
address->ipv6.port = htons(port);
+ address->ipv6.flowinfo = 0;
+ address->ipv6.scope_id = 0;
memcpy(&address->ipv6.ip, addr, hostEnt->h_length);
}
else
-#endif /* defined(_PR_INET6) */
{
PR_ASSERT(AF_INET == hostEnt->h_addrtype);
address->inet.port = htons(port);
@@ -852,46 +924,22 @@ PR_IMPLEMENT(PRStatus) PR_InitializeNetAddr(
PRStatus rv = PR_SUCCESS;
if (!_pr_initialized) _PR_ImplicitInitialization();
-#if defined(_PR_INET6)
- if (_pr_ipv6_enabled)
- {
- addr->ipv6.family = AF_INET6;
- addr->ipv6.port = htons(port);
- switch (val)
- {
- case PR_IpAddrNull:
- break; /* don't overwrite the address */
- case PR_IpAddrAny:
- addr->ipv6.ip = in6addr_any;
- break;
- case PR_IpAddrLoopback:
- addr->ipv6.ip = in6addr_loopback;
- break;
- default:
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- rv = PR_FAILURE;
- }
- }
- else
-#endif /* defined(_PR_INET6) */
- {
- addr->inet.family = AF_INET;
- addr->inet.port = htons(port);
- switch (val)
- {
- case PR_IpAddrNull:
- break; /* don't overwrite the address */
- case PR_IpAddrAny:
- addr->inet.ip = htonl(INADDR_ANY);
- break;
- case PR_IpAddrLoopback:
- addr->inet.ip = htonl(INADDR_LOOPBACK);
- break;
- default:
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- rv = PR_FAILURE;
- }
- }
+ addr->inet.family = AF_INET;
+ addr->inet.port = htons(port);
+ switch (val)
+ {
+ case PR_IpAddrNull:
+ break; /* don't overwrite the address */
+ case PR_IpAddrAny:
+ addr->inet.ip = htonl(INADDR_ANY);
+ break;
+ case PR_IpAddrLoopback:
+ addr->inet.ip = htonl(INADDR_LOOPBACK);
+ break;
+ default:
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ rv = PR_FAILURE;
+ }
return rv;
} /* PR_InitializeNetAddr */
@@ -902,19 +950,20 @@ PR_IMPLEMENT(PRStatus) PR_SetNetAddr(
if (!_pr_initialized) _PR_ImplicitInitialization();
addr->raw.family = af;
-#if defined(_PR_INET6)
- if (af == AF_INET6)
+ if (af == PR_AF_INET6)
{
addr->ipv6.port = htons(port);
+ addr->ipv6.flowinfo = 0;
+ addr->ipv6.scope_id = 0;
switch (val)
{
case PR_IpAddrNull:
break; /* don't overwrite the address */
case PR_IpAddrAny:
- addr->ipv6.ip = in6addr_any;
+ addr->ipv6.ip = _pr_in6addr_any;
break;
case PR_IpAddrLoopback:
- addr->ipv6.ip = in6addr_loopback;
+ addr->ipv6.ip = _pr_in6addr_loopback;
break;
default:
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
@@ -922,7 +971,6 @@ PR_IMPLEMENT(PRStatus) PR_SetNetAddr(
}
}
else
-#endif /* defined(_PR_INET6) */
{
addr->inet.port = htons(port);
switch (val)
@@ -946,19 +994,28 @@ PR_IMPLEMENT(PRStatus) PR_SetNetAddr(
PR_IMPLEMENT(PRBool)
PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val)
{
-#if defined(_PR_INET6)
- if (addr->raw.family == AF_INET6) {
- if (val == PR_IpAddrAny
- && IN6_IS_ADDR_UNSPECIFIED((struct in6_addr*)&addr->ipv6.ip)) {
- return PR_TRUE;
- } else if (val == PR_IpAddrLoopback
- && IN6_IS_ADDR_LOOPBACK((struct in6_addr*)&addr->ipv6.ip)) {
+ if (addr->raw.family == PR_AF_INET6) {
+ if (val == PR_IpAddrAny) {
+ if (_PR_IN6_IS_ADDR_UNSPECIFIED((PRIPv6Addr *)&addr->ipv6.ip)) {
+ return PR_TRUE;
+ } else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
+ && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
+ == htonl(INADDR_ANY)) {
+ return PR_TRUE;
+ }
+ } else if (val == PR_IpAddrLoopback) {
+ if (_PR_IN6_IS_ADDR_LOOPBACK((PRIPv6Addr *)&addr->ipv6.ip)) {
+ return PR_TRUE;
+ } else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
+ && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
+ == htonl(INADDR_LOOPBACK)) {
+ return PR_TRUE;
+ }
+ } else if (val == PR_IpAddrV4Mapped
+ && _PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)) {
return PR_TRUE;
}
- }
- else
-#endif
- {
+ } else {
if (addr->raw.family == AF_INET) {
if (val == PR_IpAddrAny && addr->inet.ip == htonl(INADDR_ANY)) {
return PR_TRUE;
@@ -971,40 +1028,258 @@ PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val)
return PR_FALSE;
}
-PR_IMPLEMENT(PRNetAddr*) PR_CreateNetAddr(PRNetAddrValue val, PRUint16 port)
+#ifndef _PR_INET6
+#define XX 127
+static const unsigned char index_hex[256] = {
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,XX,XX, XX,XX,XX,XX,
+ XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+ XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+};
+
+/*
+ * StringToV6Addr() returns 1 if the conversion succeeds,
+ * or 0 if the input is not a valid IPv6 address string.
+ * (Same as inet_pton(AF_INET6, string, addr).)
+ */
+static int StringToV6Addr(const char *string, PRIPv6Addr *addr)
{
- PRNetAddr *addr = NULL;
- if ((PR_IpAddrAny == val) || (PR_IpAddrLoopback == val))
- {
- addr = PR_NEWZAP(PRNetAddr);
- if (NULL == addr)
- PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
- else
- if (PR_FAILURE == PR_InitializeNetAddr(val, port, addr))
- PR_DELETE(addr); /* and that will make 'addr' == NULL */
+ const unsigned char *s = (const unsigned char *)string;
+ int section = 0; /* index of the current section (a 16-bit
+ * piece of the address */
+ int double_colon = -1; /* index of the section after the first
+ * 16-bit group of zeros represented by
+ * the double colon */
+ unsigned int val;
+ int len;
+
+ /* Handle initial (double) colon */
+ if (*s == ':') {
+ if (s[1] != ':') return 0;
+ s += 2;
+ addr->pr_s6_addr16[0] = 0;
+ section = double_colon = 1;
}
- else
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- return addr;
-} /* PR_CreateNetAddr */
-PR_IMPLEMENT(PRStatus) PR_DestroyNetAddr(PRNetAddr *addr)
+ 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
+
+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)
{
- PR_Free(addr);
- return PR_SUCCESS;
-} /* PR_DestroyNetAddr */
+#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_INET6 */
PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
{
PRStatus status = PR_SUCCESS;
-
-#if defined(_PR_INET6)
PRIntn rv;
+#if defined(_PR_INET6)
rv = inet_pton(AF_INET6, string, &addr->ipv6.ip);
if (1 == rv)
{
- addr->raw.family = AF_INET6;
+ addr->raw.family = PR_AF_INET6;
}
else
{
@@ -1022,6 +1297,13 @@ PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
}
}
#else /* _PR_INET6 */
+ rv = StringToV6Addr(string, &addr->ipv6.ip);
+ if (1 == rv) {
+ addr->raw.family = PR_AF_INET6;
+ return PR_SUCCESS;
+ }
+ PR_ASSERT(0 == rv);
+
addr->inet.family = AF_INET;
#ifdef XP_OS2_VACPP
addr->inet.ip = inet_addr((char *)string);
@@ -1044,17 +1326,20 @@ PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
PR_IMPLEMENT(PRStatus) PR_NetAddrToString(
const PRNetAddr *addr, char *string, PRUint32 size)
{
-#if defined(_PR_INET6)
- if (AF_INET6 == addr->raw.family)
+ if (PR_AF_INET6 == addr->raw.family)
{
+#if defined(_PR_INET6)
if (NULL == inet_ntop(AF_INET6, &addr->ipv6.ip, string, size))
+#else
+ if (NULL == V6AddrToString(&addr->ipv6.ip, string, size))
+#endif
{
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, errno);
+ /* the size of the result buffer is inadequate */
+ PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
return PR_FAILURE;
}
}
else
-#endif /* defined(_PR_INET6) */
{
PR_ASSERT(AF_INET == addr->raw.family);
PR_ASSERT(size >= 16);
@@ -1076,17 +1361,27 @@ failed:
} /* PR_NetAddrToString */
+/*
+ * Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr
+ */
+PR_IMPLEMENT(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr)
+{
+ PRUint8 *dstp;
+ dstp = v6addr->pr_s6_addr;
+ memset(dstp, 0, 10);
+ memset(dstp + 10, 0xff, 2);
+ memcpy(dstp + 12,(char *) &v4addr, 4);
+}
+
PR_IMPLEMENT(PRUint16) PR_ntohs(PRUint16 n) { return ntohs(n); }
PR_IMPLEMENT(PRUint32) PR_ntohl(PRUint32 n) { return ntohl(n); }
PR_IMPLEMENT(PRUint16) PR_htons(PRUint16 n) { return htons(n); }
PR_IMPLEMENT(PRUint32) PR_htonl(PRUint32 n) { return htonl(n); }
PR_IMPLEMENT(PRUint64) PR_ntohll(PRUint64 n)
{
- /*
- ** There is currently no attempt to optomize out depending
- ** on the host' byte order. That would be easy enough to
- ** do.
- */
+#ifdef IS_BIG_ENDIAN
+ return n;
+#else
PRUint64 tmp;
PRUint32 hi, lo;
LL_L2UI(lo, n);
@@ -1094,20 +1389,19 @@ PR_IMPLEMENT(PRUint64) PR_ntohll(PRUint64 n)
LL_L2UI(hi, tmp);
hi = PR_ntohl(hi);
lo = PR_ntohl(lo);
- LL_UI2L(n, hi);
+ LL_UI2L(n, lo);
LL_SHL(n, n, 32);
- LL_UI2L(tmp, lo);
+ LL_UI2L(tmp, hi);
LL_ADD(n, n, tmp);
return n;
+#endif
} /* ntohll */
PR_IMPLEMENT(PRUint64) PR_htonll(PRUint64 n)
{
- /*
- ** There is currently no attempt to optomize out depending
- ** on the host' byte order. That would be easy enough to
- ** do.
- */
+#ifdef IS_BIG_ENDIAN
+ return n;
+#else
PRUint64 tmp;
PRUint32 hi, lo;
LL_L2UI(lo, n);
@@ -1115,18 +1409,10 @@ PR_IMPLEMENT(PRUint64) PR_htonll(PRUint64 n)
LL_L2UI(hi, tmp);
hi = htonl(hi);
lo = htonl(lo);
- LL_UI2L(n, hi);
+ LL_UI2L(n, lo);
LL_SHL(n, n, 32);
- LL_UI2L(tmp, lo);
+ LL_UI2L(tmp, hi);
LL_ADD(n, n, tmp);
return n;
-} /* htonll */
-
-PR_IMPLEMENT(PRUint16) PR_FamilyInet(void)
-{
-#ifdef _PR_INET6
- return (_pr_ipv6_enabled ? AF_INET6 : AF_INET);
-#else
- return AF_INET;
#endif
-}
+} /* htonll */
diff --git a/pr/src/misc/prtpool.c b/pr/src/misc/prtpool.c
index 64aa8426..b694b94a 100644
--- a/pr/src/misc/prtpool.c
+++ b/pr/src/misc/prtpool.c
@@ -16,7 +16,6 @@
* Reserved.
*/
-#include "prtpool.h"
#include "nspr.h"
/*
@@ -84,10 +83,11 @@ struct PRThreadPool {
PRInt32 max_threads;
PRInt32 current_threads;
PRInt32 idle_threads;
- PRInt32 stacksize;
+ PRUint32 stacksize;
tp_jobq jobq;
io_jobq ioq;
timer_jobq timerq;
+ PRLock *join_lock; /* used with jobp->join_cv */
PRCondVar *shutdown_cv;
PRBool shutdown;
};
@@ -95,12 +95,6 @@ struct PRThreadPool {
typedef enum io_op_type
{ JOB_IO_READ, JOB_IO_WRITE, JOB_IO_CONNECT, JOB_IO_ACCEPT } io_op_type;
-typedef enum _PRJobStatus
- { JOB_ON_TIMERQ, JOB_ON_IOQ, JOB_QUEUED, JOB_RUNNING, JOB_COMPLETED,
- JOB_CANCELED, JOB_FREED } _PRJobStatus;
-
-typedef void (* Jobfn)(void *arg);
-
#ifdef OPT_WINNT
typedef struct NT_notifier {
OVERLAPPED overlapped; /* must be first */
@@ -110,12 +104,14 @@ typedef struct NT_notifier {
struct PRJob {
PRCList links; /* for linking jobs */
- _PRJobStatus status;
- PRBool joinable;
- Jobfn job_func;
+ PRBool on_ioq; /* job on ioq */
+ PRBool on_timerq; /* job on timerq */
+ PRJobFn job_func;
void *job_arg;
- PRLock *jlock;
PRCondVar *join_cv;
+ PRBool join_wait; /* == PR_TRUE, when waiting to join */
+ PRCondVar *cancel_cv; /* for cancelling IO jobs */
+ PRBool cancel_io; /* for cancelling IO jobs */
PRThreadPool *tpool; /* back pointer to thread pool */
PRJobIoDesc *iod;
io_op_type io_op;
@@ -134,13 +130,41 @@ struct PRJob {
#define WTHREAD_LINKS_PTR(_qp) \
((wthread *) ((char *) (_qp) - offsetof(wthread, links)))
+#define JOINABLE_JOB(_jobp) (NULL != (_jobp)->join_cv)
+
+#define JOIN_NOTIFY(_jobp) \
+ PR_BEGIN_MACRO \
+ PR_Lock(_jobp->tpool->join_lock); \
+ _jobp->join_wait = PR_FALSE; \
+ PR_NotifyCondVar(_jobp->join_cv); \
+ PR_Unlock(_jobp->tpool->join_lock); \
+ PR_END_MACRO
+
+#define CANCEL_IO_JOB(jobp) \
+ PR_BEGIN_MACRO \
+ jobp->cancel_io = PR_FALSE; \
+ jobp->on_ioq = PR_FALSE; \
+ PR_REMOVE_AND_INIT_LINK(&jobp->links); \
+ tp->ioq.cnt--; \
+ PR_NotifyCondVar(jobp->cancel_cv); \
+ PR_END_MACRO
+
static void delete_job(PRJob *jobp);
static PRThreadPool * alloc_threadpool();
-static PRJob * alloc_job(PRBool joinable);
+static PRJob * alloc_job(PRBool joinable, PRThreadPool *tp);
static void notify_ioq(PRThreadPool *tp);
static void notify_timerq(PRThreadPool *tp);
/*
+ * locks are acquired in the following order
+ *
+ * tp->ioq.lock,tp->timerq.lock
+ * |
+ * V
+ * tp->jobq->lock
+ */
+
+/*
* worker thread function
*/
static void wstart(void *arg)
@@ -172,17 +196,14 @@ PRCList *head;
tp->idle_threads--;
tp->jobq.cnt--;
PR_Unlock(tp->jobq.lock);
- PR_Lock(jobp->jlock);
- jobp->status = JOB_RUNNING;
- PR_Unlock(jobp->jlock);
#else
PR_Lock(tp->jobq.lock);
while (PR_CLIST_IS_EMPTY(&tp->jobq.list) && (!tp->shutdown)) {
tp->idle_threads++;
PR_WaitCondVar(tp->jobq.cv, PR_INTERVAL_NO_TIMEOUT);
+ tp->idle_threads--;
}
- tp->idle_threads--;
if (tp->shutdown) {
PR_Unlock(tp->jobq.lock);
break;
@@ -194,20 +215,14 @@ PRCList *head;
PR_REMOVE_AND_INIT_LINK(head);
tp->jobq.cnt--;
jobp = JOB_LINKS_PTR(head);
- PR_Lock(jobp->jlock);
- jobp->status = JOB_RUNNING;
- PR_Unlock(jobp->jlock);
PR_Unlock(tp->jobq.lock);
#endif
jobp->job_func(jobp->job_arg);
- if (!jobp->joinable) {
+ if (!JOINABLE_JOB(jobp)) {
delete_job(jobp);
} else {
- PR_Lock(jobp->jlock);
- jobp->status = JOB_COMPLETED;
- PR_NotifyCondVar(jobp->join_cv);
- PR_Unlock(jobp->jlock);
+ JOIN_NOTIFY(jobp);
}
}
PR_Lock(tp->jobq.lock);
@@ -236,11 +251,9 @@ add_to_jobq(PRThreadPool *tp, PRJob *jobp)
#else
PR_Lock(tp->jobq.lock);
PR_APPEND_LINK(&jobp->links,&tp->jobq.list);
- jobp->status = JOB_QUEUED;
tp->jobq.cnt++;
if ((tp->idle_threads < tp->jobq.cnt) &&
(tp->current_threads < tp->max_threads)) {
- PRThread *thr;
wthread *wthrp;
/*
* increment thread count and unlock the jobq lock
@@ -248,15 +261,19 @@ add_to_jobq(PRThreadPool *tp, PRJob *jobp)
tp->current_threads++;
PR_Unlock(tp->jobq.lock);
/* create new worker thread */
- thr = PR_CreateThread(PR_USER_THREAD, wstart,
+ wthrp = PR_NEWZAP(wthread);
+ if (wthrp) {
+ wthrp->thread = PR_CreateThread(PR_USER_THREAD, wstart,
tp, PR_PRIORITY_NORMAL,
PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,tp->stacksize);
+ if (NULL == wthrp->thread) {
+ PR_DELETE(wthrp); /* this sets wthrp to NULL */
+ }
+ }
PR_Lock(tp->jobq.lock);
- if (NULL == thr) {
+ if (NULL == wthrp) {
tp->current_threads--;
} else {
- wthrp = PR_NEWZAP(wthread);
- wthrp->thread = thr;
PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads);
}
}
@@ -331,6 +348,10 @@ PRIntervalTime now;
PR_Lock(tp->ioq.lock);
for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = qp->next) {
jobp = JOB_LINKS_PTR(qp);
+ if (jobp->cancel_io) {
+ CANCEL_IO_JOB(jobp);
+ continue;
+ }
if (pollfds_used == (pollfd_cnt))
break;
pollfds[pollfds_used].fd = jobp->iod->socket;
@@ -391,11 +412,18 @@ PRIntervalTime now;
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 */
@@ -403,21 +431,36 @@ PRIntervalTime now;
jobp->iod->error = PR_BAD_DESCRIPTOR_ERROR;
else if (PR_POLL_HUP & revents)
jobp->iod->error = PR_CONNECT_RESET_ERROR;
+ else
+ jobp->iod->error = PR_IO_ERROR;
/*
* add to jobq
*/
add_to_jobq(tp, jobp);
- } else if (revents & events) {
+ } else if (revents) {
/*
* add to jobq
*/
PR_Lock(tp->ioq.lock);
+ if (jobp->cancel_io) {
+ CANCEL_IO_JOB(jobp);
+ PR_Unlock(tp->ioq.lock);
+ continue;
+ }
PR_REMOVE_AND_INIT_LINK(&jobp->links);
tp->ioq.cnt--;
+ jobp->on_ioq = PR_FALSE;
PR_Unlock(tp->ioq.lock);
- jobp->iod->error = 0;
+ if (jobp->io_op == JOB_IO_CONNECT) {
+ if (PR_GetConnectStatus(&pollfds[index]) == PR_SUCCESS)
+ jobp->iod->error = 0;
+ else
+ jobp->iod->error = PR_GetError();
+ } else
+ jobp->iod->error = 0;
+
add_to_jobq(tp, jobp);
}
}
@@ -429,6 +472,10 @@ PRIntervalTime now;
PR_Lock(tp->ioq.lock);
for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = qp->next) {
jobp = JOB_LINKS_PTR(qp);
+ if (jobp->cancel_io) {
+ CANCEL_IO_JOB(jobp);
+ continue;
+ }
if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout)
break;
if ((PR_INTERVAL_NO_WAIT != jobp->timeout) &&
@@ -436,6 +483,7 @@ PRIntervalTime now;
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);
}
@@ -494,6 +542,7 @@ PRIntervalTime now;
*/
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);
@@ -510,6 +559,8 @@ delete_threadpool(PRThreadPool *tp)
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);
@@ -545,6 +596,9 @@ PRThreadPool *tp;
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);
@@ -581,7 +635,7 @@ failed:
/* Create thread pool */
PR_IMPLEMENT(PRThreadPool *)
PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads,
- PRSize stacksize)
+ PRUint32 stacksize)
{
PRThreadPool *tp;
PRThread *thr;
@@ -643,32 +697,29 @@ static void
delete_job(PRJob *jobp)
{
if (NULL != jobp) {
- if (NULL != jobp->jlock) {
- PR_DestroyLock(jobp->jlock);
- jobp->jlock = NULL;
- }
if (NULL != jobp->join_cv) {
PR_DestroyCondVar(jobp->join_cv);
jobp->join_cv = NULL;
}
- jobp->status = JOB_FREED;
+ if (NULL != jobp->cancel_cv) {
+ PR_DestroyCondVar(jobp->cancel_cv);
+ jobp->cancel_cv = NULL;
+ }
PR_DELETE(jobp);
}
}
static PRJob *
-alloc_job(PRBool joinable)
+alloc_job(PRBool joinable, PRThreadPool *tp)
{
PRJob *jobp;
jobp = PR_NEWZAP(PRJob);
if (NULL == jobp)
goto failed;
- jobp->jlock = PR_NewLock();
- if (NULL == jobp->jlock)
- goto failed;
if (joinable) {
- jobp->join_cv = PR_NewCondVar(jobp->jlock);
+ jobp->join_cv = PR_NewCondVar(tp->join_lock);
+ jobp->join_wait = PR_TRUE;
if (NULL == jobp->join_cv)
goto failed;
} else {
@@ -686,32 +737,31 @@ failed:
/* queue a job */
PR_IMPLEMENT(PRJob *)
-PR_QueueJob(PRThreadPool *tpool, JobFn fn, void *arg, PRBool joinable)
+PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable)
{
PRJob *jobp;
- jobp = alloc_job(joinable);
+ jobp = alloc_job(joinable, tpool);
if (NULL == jobp)
return NULL;
jobp->job_func = fn;
jobp->job_arg = arg;
jobp->tpool = tpool;
- jobp->joinable = joinable;
add_to_jobq(tpool, jobp);
return jobp;
}
-/* queue a job, when a socket is readable */
+/* queue a job, when a socket is readable or writeable */
static PRJob *
-queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
+queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg,
PRBool joinable, io_op_type op)
{
PRJob *jobp;
PRIntervalTime now;
- jobp = alloc_job(joinable);
+ jobp = alloc_job(joinable, tpool);
if (NULL == jobp) {
return NULL;
}
@@ -723,9 +773,7 @@ queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
jobp->job_func = fn;
jobp->job_arg = arg;
- jobp->status = JOB_ON_IOQ;
jobp->tpool = tpool;
- jobp->joinable = joinable;
jobp->iod = iod;
if (JOB_IO_READ == op) {
jobp->io_op = JOB_IO_READ;
@@ -738,7 +786,7 @@ queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
jobp->io_poll_flags = PR_POLL_READ;
} else if (JOB_IO_CONNECT == op) {
jobp->io_op = JOB_IO_CONNECT;
- jobp->io_poll_flags = PR_POLL_WRITE;
+ jobp->io_poll_flags = PR_POLL_WRITE|PR_POLL_EXCEPT;
} else {
delete_job(jobp);
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
@@ -778,6 +826,7 @@ queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
PR_INSERT_AFTER(&jobp->links,qp);
}
+ jobp->on_ioq = PR_TRUE;
tpool->ioq.cnt++;
/*
* notify io worker thread(s)
@@ -789,7 +838,7 @@ queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
/* queue a job, when a socket is readable */
PR_IMPLEMENT(PRJob *)
-PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
+PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg,
PRBool joinable)
{
return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_READ));
@@ -797,7 +846,7 @@ PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
/* queue a job, when a socket is writeable */
PR_IMPLEMENT(PRJob *)
-PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn,void * arg,
+PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn,void * arg,
PRBool joinable)
{
return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_WRITE));
@@ -806,27 +855,40 @@ PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn,void * arg,
/* queue a job, when a socket has a pending connection */
PR_IMPLEMENT(PRJob *)
-PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
- PRBool joinable)
+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, PRNetAddr *addr,
- JobFn fn, void * arg, PRBool joinable)
+PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod,
+ const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable)
{
- /*
- * not implemented
- */
- return NULL;
+ 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,
- JobFn fn, void * arg, PRBool joinable)
+ PRJobFn fn, void * arg, PRBool joinable)
{
PRIntervalTime now;
PRJob *jobp;
@@ -841,7 +903,7 @@ PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout,
*/
return(PR_QueueJob(tpool, fn, arg, joinable));
}
- jobp = alloc_job(joinable);
+ jobp = alloc_job(joinable, tpool);
if (NULL == jobp) {
return NULL;
}
@@ -853,9 +915,7 @@ PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout,
jobp->job_func = fn;
jobp->job_arg = arg;
- jobp->status = JOB_ON_TIMERQ;
jobp->tpool = tpool;
- jobp->joinable = joinable;
jobp->timeout = timeout;
now = PR_IntervalNow();
@@ -863,6 +923,7 @@ PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime 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 {
@@ -921,27 +982,64 @@ PR_CancelJob(PRJob *jobp) {
PRStatus rval = PR_FAILURE;
PRThreadPool *tp;
- if (JOB_QUEUED == jobp->status) {
+ if (jobp->on_timerq) {
/*
- * now, check again while holding thread pool lock
+ * now, check again while holding the timerq lock
*/
tp = jobp->tpool;
- PR_Lock(tp->jobq.lock);
- PR_Lock(jobp->jlock);
- if (JOB_QUEUED == jobp->status) {
+ PR_Lock(tp->timerq.lock);
+ if (jobp->on_timerq) {
+ jobp->on_timerq = PR_FALSE;
PR_REMOVE_AND_INIT_LINK(&jobp->links);
- if (!jobp->joinable) {
- PR_Unlock(jobp->jlock);
+ tp->timerq.cnt--;
+ PR_Unlock(tp->timerq.lock);
+ if (!JOINABLE_JOB(jobp)) {
delete_job(jobp);
} else {
- jobp->status = JOB_CANCELED;
- PR_NotifyCondVar(jobp->join_cv);
- PR_Unlock(jobp->jlock);
+ JOIN_NOTIFY(jobp);
}
rval = PR_SUCCESS;
- }
- PR_Unlock(tp->jobq.lock);
+ } 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;
}
@@ -949,19 +1047,14 @@ PR_CancelJob(PRJob *jobp) {
PR_IMPLEMENT(PRStatus)
PR_JoinJob(PRJob *jobp)
{
- /*
- * No references to the thread pool
- */
- if (!jobp->joinable) {
+ if (!JOINABLE_JOB(jobp)) {
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return PR_FAILURE;
}
- PR_Lock(jobp->jlock);
- while((JOB_COMPLETED != jobp->status) &&
- (JOB_CANCELED != jobp->status))
+ PR_Lock(jobp->tpool->join_lock);
+ while(jobp->join_wait)
PR_WaitCondVar(jobp->join_cv, PR_INTERVAL_NO_TIMEOUT);
-
- PR_Unlock(jobp->jlock);
+ PR_Unlock(jobp->tpool->join_lock);
delete_job(jobp);
return PR_SUCCESS;
}
@@ -1017,9 +1110,7 @@ PRStatus rval_status;
/*
* wakeup io thread(s)
*/
- PR_Lock(tpool->ioq.lock);
notify_ioq(tpool);
- PR_Unlock(tpool->ioq.lock);
/*
* wakeup timer thread(s)
@@ -1064,7 +1155,7 @@ PRStatus rval_status;
}
/*
- * Delete unjoinable jobs; joinable jobs must be reclaimed by the user
+ * Delete queued jobs
*/
while (!PR_CLIST_IS_EMPTY(&tpool->jobq.list)) {
PRJob *jobp;
@@ -1073,17 +1164,10 @@ PRStatus rval_status;
PR_REMOVE_AND_INIT_LINK(head);
jobp = JOB_LINKS_PTR(head);
tpool->jobq.cnt--;
-
- if (!jobp->joinable) {
- delete_job(jobp);
- } else {
- PR_Lock(jobp->jlock);
- jobp->status = JOB_CANCELED;
- PR_NotifyCondVar(jobp->join_cv);
- PR_Unlock(jobp->jlock);
- }
+ delete_job(jobp);
}
+ /* delete io jobs */
while (!PR_CLIST_IS_EMPTY(&tpool->ioq.list)) {
PRJob *jobp;
@@ -1091,16 +1175,10 @@ PRStatus rval_status;
PR_REMOVE_AND_INIT_LINK(head);
tpool->ioq.cnt--;
jobp = JOB_LINKS_PTR(head);
- if (!jobp->joinable) {
- delete_job(jobp);
- } else {
- PR_Lock(jobp->jlock);
- jobp->status = JOB_CANCELED;
- PR_NotifyCondVar(jobp->join_cv);
- PR_Unlock(jobp->jlock);
- }
+ delete_job(jobp);
}
+ /* delete timer jobs */
while (!PR_CLIST_IS_EMPTY(&tpool->timerq.list)) {
PRJob *jobp;
@@ -1108,14 +1186,7 @@ PRStatus rval_status;
PR_REMOVE_AND_INIT_LINK(head);
tpool->timerq.cnt--;
jobp = JOB_LINKS_PTR(head);
- if (!jobp->joinable) {
- delete_job(jobp);
- } else {
- PR_Lock(jobp->jlock);
- jobp->status = JOB_CANCELED;
- PR_NotifyCondVar(jobp->join_cv);
- PR_Unlock(jobp->jlock);
- }
+ delete_job(jobp);
}
PR_ASSERT(0 == tpool->jobq.cnt);
diff --git a/pr/src/nspr.rc b/pr/src/nspr.rc
index 147b670b..ae4bf876 100644
--- a/pr/src/nspr.rc
+++ b/pr/src/nspr.rc
@@ -22,6 +22,10 @@
#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
@@ -66,7 +70,7 @@ BEGIN
VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
VALUE "FileVersion", PR_VERSION "\0"
VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "LegalCopyright", "Copyright \251 1996-1999 Netscape Communications Corporation\0"
+ VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
VALUE "ProductName", "Netscape Portable Runtime\0"
VALUE "ProductVersion", PR_VERSION "\0"
diff --git a/pr/src/prvrsion.c b/pr/src/prvrsion.c
index 54a292f2..c694a34e 100644
--- a/pr/src/prvrsion.c
+++ b/pr/src/prvrsion.c
@@ -42,7 +42,14 @@
#define _DEBUG_STRING ""
#endif
-PRVersionDescription prVersionDescription_libnspr3 =
+/*
+ * 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 */
@@ -92,7 +99,7 @@ PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void)
dummy = rcsid;
dummy = sccsid;
#endif
- return &prVersionDescription_libnspr3;
+ return &VERSION_DESC_NAME;
} /* versionEntryPointType */
/* prvrsion.c */
diff --git a/pr/src/pthreads/ptio.c b/pr/src/pthreads/ptio.c
index f65dbdcc..b301ebd5 100644
--- a/pr/src/pthreads/ptio.c
+++ b/pr/src/pthreads/ptio.c
@@ -143,7 +143,8 @@ static ssize_t (*pt_aix_sendfile_fptr)() = NULL;
#error "Cannot determine architecture"
#endif
-static PRFileDesc *pt_SetMethods(PRIntn osfd, PRDescType type);
+static PRFileDesc *pt_SetMethods(
+ PRIntn osfd, PRDescType type, PRBool isAcceptedSocket);
static PRLock *_pr_flock_lock; /* For PR_LockFile() etc. */
static PRLock *_pr_rename_lock; /* For PR_Rename() */
@@ -153,13 +154,11 @@ static PRLock *_pr_rename_lock; /* For PR_Rename() */
/* These two functions are only used in assertions. */
#if defined(DEBUG)
-static PRBool IsValidNetAddr(const PRNetAddr *addr)
+PRBool IsValidNetAddr(const PRNetAddr *addr)
{
if ((addr != NULL)
&& (addr->raw.family != AF_UNIX)
-#ifdef _PR_INET6
- && (addr->raw.family != AF_INET6)
-#endif
+ && (addr->raw.family != PR_AF_INET6)
&& (addr->raw.family != AF_INET)) {
return PR_FALSE;
}
@@ -190,7 +189,7 @@ static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len)
* 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 100
+#define PT_DEFAULT_POLL_MSEC 5000
/*
* pt_SockLen is the type for the length of a socket address
@@ -217,17 +216,11 @@ typedef PRBool (*ContinuationFn)(pt_Continuation *op, PRInt16 revents);
typedef enum pr_ContuationStatus
{
pt_continuation_pending,
- pt_continuation_recycle,
- 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 */
-
- PRFileDesc *fd;
/* The building of the continuation operation */
ContinuationFn function; /* what function to continue */
union { PRIntn osfd; } arg1; /* #1 - the op's fd */
@@ -258,7 +251,6 @@ struct pt_Continuation
#endif /* HPUX11 */
PRIntervalTime timeout; /* client (relative) timeout */
- PRIntervalTime absolute; /* internal (absolute) timeout */
PRInt16 event; /* flags for poll()'s events */
@@ -271,27 +263,8 @@ struct pt_Continuation
PRIntn syserrno; /* in case it failed, why (errno) */
pr_ContuationStatus status; /* the status of the operation */
- PRCondVar *complete; /* to notify the initiating thread */
- PRIntn io_tq_index; /* io-queue index */
};
-static struct pt_TimedQueue
-{
- PRLock *ml; /* a little protection */
- PRThread *thread; /* internal thread's identification */
- 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 */
- struct pollfd *pollingList; /* list built for polling */
- PRIntn pollingSlotsAllocated; /* # entries available in list */
- pt_Continuation **pollingOps; /* list paralleling polling list */
-} *pt_tqp; /* an array */
-
-static PRIntn _pt_num_cpus;
-PRIntn _pt_tq_count; /* size of the pt_tqp array */
-static PRInt32 _pt_tq_index; /* atomically incremented */
-
#if defined(DEBUG)
PTDebug pt_debug; /* this is shared between several modules */
@@ -316,16 +289,6 @@ PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg)
PR_fprintf(
debug_out, "\tstarted: %s[%lld]\n", buffer, elapsed);
PR_fprintf(
- debug_out, "\tmissed predictions: %u\n", stats.predictionsFoiled);
- PR_fprintf(
- debug_out, "\tpollingList max: %u\n", stats.pollingListMax);
- PR_fprintf(
- debug_out, "\tcontinuations served: %u\n", stats.continuationsServed);
- PR_fprintf(
- debug_out, "\trecycles needed: %u\n", stats.recyclesNeeded);
- PR_fprintf(
- debug_out, "\tquiescent IO: %u\n", stats.quiescentIO);
- PR_fprintf(
debug_out, "\tlocks [created: %u, destroyed: %u]\n",
stats.locks_created, stats.locks_destroyed);
PR_fprintf(
@@ -341,647 +304,143 @@ PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg)
#endif /* DEBUG */
-/*
- * The following two functions, pt_InsertTimedInternal and
- * pt_FinishTimedInternal, are always called with the tqp->ml
- * lock held. The "internal" in the functions' names come from
- * the Mesa programming language. Internal functions are always
- * called from inside a monitor.
- */
-
-static void pt_InsertTimedInternal(pt_Continuation *op)
-{
- pt_Continuation *t_op = NULL;
- PRIntervalTime now = PR_IntervalNow();
- struct pt_TimedQueue *tqp = &pt_tqp[op->io_tq_index];
-
-#if defined(DEBUG)
- {
- PRIntn count;
- pt_Continuation *tmp;
- PRThread *self = PR_GetCurrentThread();
-
- PR_ASSERT(tqp == &pt_tqp[self->io_tq_index]);
- PR_ASSERT((tqp->head == NULL) == (tqp->tail == NULL));
- PR_ASSERT((tqp->head == NULL) == (tqp->op_count == 0));
- for (tmp = tqp->head, count = 0; tmp != NULL; tmp = tmp->next) count += 1;
- PR_ASSERT(count == tqp->op_count);
- for (tmp = tqp->tail, count = 0; tmp != NULL; tmp = tmp->prev) count += 1;
- PR_ASSERT(count == tqp->op_count);
- for (tmp = tqp->head; tmp != NULL; tmp = tmp->next)
- PR_ASSERT(tmp->io_tq_index == op->io_tq_index);
- }
-#endif /* defined(DEBUG) */
-
- /*
- * If this element operation isn't timed, it gets queued at the
- * end of the list (just after tqp->tail) and we're
- * finishd early.
- */
- if (PR_INTERVAL_NO_TIMEOUT == op->timeout)
- {
- t_op = tqp->tail; /* put it at the end */
- goto done;
- }
-
- /*
- * The portion of this routine deals with timed ops.
- */
- op->absolute = now + op->timeout; /* absolute ticks */
- if (NULL == tqp->op) tqp->op = op;
- else
- {
- /*
- * To find where in the list to put the new operation, based
- * on the absolute time the operation in question will expire.
- *
- * The new operation ('op') will expire at now() + op->timeout.
- *
- * This should be easy!
- */
-
- for (t_op = tqp->op; NULL != t_op; t_op = t_op->prev)
- {
- /*
- * 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 difference 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 computed.
- */
- if ((PRInt32)(op->absolute - t_op->absolute) >= 0)
- {
- if (t_op == tqp->op) tqp->op = op;
- break;
- }
- }
- }
-
-done:
-
- /*
- * Insert 'op' into the queue just after t_op or if t_op is null,
- * at the head of the list.
- *
- * We need to set up the 'next' and 'prev' pointers of 'op'
- * correctly before inserting 'op' into the queue. Also, we insert
- * 'op' by updating tqp->head or op->prev->next first, and then
- * updating op->next->prev. We want to make sure that the 'next'
- * pointers are linked up correctly at all times so that we can
- * traverse the queue by starting with tqp->head and following
- * the 'next' pointers, without having to acquire the tqp->ml lock.
- * (we do that in pt_ContinuationThreadInternal). We traverse the 'prev'
- * pointers only in this function, which is called with the lock held.
- *
- * Similar care is taken in pt_FinishTimedInternal where we remove
- * an op from the queue.
- */
- if (NULL == t_op)
- {
- op->prev = NULL;
- op->next = tqp->head;
- tqp->head = op;
- if (NULL == tqp->tail) tqp->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 == tqp->tail)
- tqp->tail = op;
- }
-
- tqp->op_count += 1;
-
-#if defined(DEBUG)
- {
- PRIntn count;
- pt_Continuation *tmp;
- PR_ASSERT(tqp->head != NULL);
- PR_ASSERT(tqp->tail != NULL);
- PR_ASSERT(tqp->op_count != 0);
- PR_ASSERT(tqp->head->prev == NULL);
- PR_ASSERT(tqp->tail->next == NULL);
- if (tqp->op_count > 1)
- {
- PR_ASSERT(tqp->head->next != NULL);
- PR_ASSERT(tqp->tail->prev != NULL);
- }
- else
- {
- PR_ASSERT(tqp->head->next == NULL);
- PR_ASSERT(tqp->tail->prev == NULL);
- }
- for (tmp = tqp->head, count = 0; tmp != NULL; tmp = tmp->next) count += 1;
- PR_ASSERT(count == tqp->op_count);
- for (tmp = tqp->tail, count = 0; tmp != NULL; tmp = tmp->prev) count += 1;
- PR_ASSERT(count == tqp->op_count);
- }
-#endif /* defined(DEBUG) */
-
-} /* pt_InsertTimedInternal */
-
-/*
- * function: pt_FinishTimedInternal
- *
- * 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)
+static void pt_poll_now(pt_Continuation *op)
{
- pt_Continuation *next;
- struct pt_TimedQueue *tqp = &pt_tqp[op->io_tq_index];
-
-#if defined(DEBUG)
- {
- PRIntn count;
- pt_Continuation *tmp;
- PR_ASSERT(tqp->head != NULL);
- PR_ASSERT(tqp->tail != NULL);
- PR_ASSERT(tqp->op_count != 0);
- PR_ASSERT(tqp->head->prev == NULL);
- PR_ASSERT(tqp->tail->next == NULL);
- if (tqp->op_count > 1)
- {
- PR_ASSERT(tqp->head->next != NULL);
- PR_ASSERT(tqp->tail->prev != NULL);
- }
- else
- {
- PR_ASSERT(tqp->head->next == NULL);
- PR_ASSERT(tqp->tail->prev == NULL);
- }
- for (tmp = tqp->head, count = 0; tmp != NULL; tmp = tmp->next) count += 1;
- PR_ASSERT(count == tqp->op_count);
- for (tmp = tqp->tail, count = 0; tmp != NULL; tmp = tmp->prev) count += 1;
- PR_ASSERT(count == tqp->op_count);
- }
-#endif /* defined(DEBUG) */
-
- /* remove this one from the list */
- if (NULL == op->prev) tqp->head = op->next;
- else op->prev->next = op->next;
- if (NULL == op->next) tqp->tail = op->prev;
- else op->next->prev = op->prev;
-
- /* did we happen to hit the timed op? */
- if (op == tqp->op) tqp->op = op->prev;
-
- next = op->next;
- op->next = op->prev = NULL;
- op->status = pt_continuation_done;
-
- tqp->op_count -= 1;
-
-#if defined(DEBUG)
- pt_debug.continuationsServed += 1;
-#endif
- PR_NotifyCondVar(op->complete);
-
-#if defined(DEBUG)
- {
- PRIntn count;
- pt_Continuation *tmp;
- PR_ASSERT((tqp->head == NULL) == (tqp->tail == NULL));
- PR_ASSERT((tqp->head == NULL) == (tqp->op_count == 0));
- for (tmp = tqp->head, count = 0; tmp != NULL; tmp = tmp->next) count += 1;
- PR_ASSERT(count == tqp->op_count);
- for (tmp = tqp->tail, count = 0; tmp != NULL; tmp = tmp->prev) count += 1;
- PR_ASSERT(count == tqp->op_count);
- }
-#endif /* defined(DEBUG) */
-
- return next;
-} /* pt_FinishTimedInternal */
-
-static void pt_ContinuationThreadInternal(pt_Continuation *my_op)
-{
- /* initialization */
- PRInt32 msecs, mx_poll_ticks;
- PRThreadPriority priority; /* used to save caller's prio */
- PRIntn pollingListUsed; /* # entries used in the list */
- PRIntn pollingListNeeded; /* # entries needed this time */
- PRIntn io_tq_index = my_op->io_tq_index;
- struct pt_TimedQueue *tqp = &pt_tqp[my_op->io_tq_index];
- struct pollfd *pollingList = tqp->pollingList;
- PRIntn pollingSlotsAllocated = tqp->pollingSlotsAllocated;
- pt_Continuation **pollingOps = tqp->pollingOps;
-
- PR_Unlock(tqp->ml); /* don't need that silly lock for a bit */
-
- priority = PR_GetThreadPriority(tqp->thread);
- PR_SetThreadPriority(tqp->thread, PR_PRIORITY_HIGH);
-
- mx_poll_ticks = (PRInt32)PR_MillisecondsToInterval(PT_DEFAULT_POLL_MSEC);
-
- /* do some real work */
- while (PR_TRUE)
- {
- PRIntn rv;
- PRInt32 timeout;
- PRIntn pollIndex;
- PRIntervalTime now;
- pt_Continuation *op, *next_op;
-
- PR_ASSERT(NULL != tqp->head);
-
- pollingListNeeded = tqp->op_count;
-
- /*
- * We are not holding the tqp->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.
- *
- * The space allocated is for both a vector that parallels the
- * polling list, providing pointers directly into the operation's
- * table and the polling list itself. There is a guard element
- * between the two structures.
- */
- pollingListNeeded += 10;
- if (pollingListNeeded > pollingSlotsAllocated)
- {
- if (NULL != pollingOps) PR_Free(pollingOps);
- pollingOps = (pt_Continuation**)PR_Malloc(
- sizeof(pt_Continuation**) + pollingListNeeded *
- (sizeof(struct pollfd) + sizeof(pt_Continuation*)));
- PR_ASSERT(NULL != pollingOps);
- tqp->pollingOps = pollingOps;
- pollingSlotsAllocated = pollingListNeeded;
- tqp->pollingSlotsAllocated = pollingSlotsAllocated;
- pollingOps[pollingSlotsAllocated] = (pt_Continuation*)-1;
- pollingList = (struct pollfd*)(&pollingOps[pollingSlotsAllocated + 1]);
- tqp->pollingList = pollingList;
-
- }
-
-#if defined(DEBUG)
- if (pollingListNeeded > pt_debug.pollingListMax)
- pt_debug.pollingListMax = pollingListNeeded;
-#endif
-
- /*
- ** This is interrupt processing. If this thread was interrupted,
- ** the thread state will have the PT_THREAD_ABORTED bit set. This
- ** overrides good completions as well as timeouts.
- **
- ** BTW, it does no good to hold the lock here. This lock doesn't
- ** protect the thread structure in any way. Testing the bit and
- ** (perhaps) resetting it are safe 'cause it's the only modifiable
- ** bit in that word.
- */
- if (_PT_THREAD_INTERRUPTED(tqp->thread))
- {
- my_op->status = pt_continuation_abort;
- tqp->thread->state &= ~PT_THREAD_ABORTED;
- }
-
-
- /*
- * 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(tqp->ml);
-
- for (op = tqp->head; NULL != op;)
- {
- if (pt_continuation_abort == op->status)
- {
- op->result.code = -1;
- op->syserrno = EINTR;
- next_op = pt_FinishTimedInternal(op);
- if (op == my_op) goto recycle;
- else op = next_op;
- PR_ASSERT(NULL != tqp->head);
- }
- else
- {
- op->status = pt_continuation_pending;
- if (pollingListUsed >= pollingSlotsAllocated)
- {
-#if defined(DEBUG)
- pt_debug.predictionsFoiled += 1;
-#endif
- break;
- }
- PR_ASSERT((pt_Continuation*)-1 == pollingOps[pollingSlotsAllocated]);
- /*
- * eventMask bitmasks are declared as PRIntn so that
- * each bitmask can be updated individually without
- * disturbing adjacent memory, but only the lower 16
- * bits of a bitmask are used.
- */
- op->fd->secret->eventMask[io_tq_index] = 0xffff;
- pollingOps[pollingListUsed] = op;
- pollingList[pollingListUsed].revents = 0;
- pollingList[pollingListUsed].fd = op->arg1.osfd;
- pollingList[pollingListUsed].events = op->event;
- pollingListUsed += 1;
- op = op->next;
- }
- }
-
- /*
- * 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 (PR_INTERVAL_NO_TIMEOUT == tqp->head->timeout)
- msecs = PT_DEFAULT_POLL_MSEC;
- else
- {
- timeout = tqp->head->absolute - PR_IntervalNow();
- if (timeout <= 0) msecs = 0; /* already timed out */
- else if (timeout >= mx_poll_ticks) msecs = PT_DEFAULT_POLL_MSEC;
- else msecs = (PRInt32)PR_IntervalToMilliseconds(timeout);
- }
-
- PR_Unlock(tqp->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) continue; /* make it rethink things */
-
- PR_ASSERT((pt_Continuation*)-1 == pollingOps[pollingSlotsAllocated]);
-
- rv = poll(pollingList, pollingListUsed, msecs);
-
- if ((-1 == rv) && ((errno == EINTR) || (errno == EAGAIN)))
- continue; /* go around the loop again */
-
- if (rv > 0)
- {
- /*
- * poll() says that something in our list is ready for some more
- * action. Find it, load up the operation and see what happens.
- */
-
- /*
- * 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.
- */
-
- for (pollIndex = 0; pollIndex < pollingListUsed; ++pollIndex)
- {
- PRInt16 events = pollingList[pollIndex].events;
- PRInt16 revents = pollingList[pollIndex].revents;
-
- op = pollingOps[pollIndex]; /* this is the operation */
-
- /* (ref: Bug #153459)
- ** In case of POLLERR we let the operation retry in hope
- ** of getting a more definitive OS error.
- */
- if ((revents & POLLNVAL) /* busted in all cases */
- || ((events & POLLOUT) && (revents & POLLHUP))) /* write op & hup */
- {
- PR_Lock(tqp->ml);
- op->result.code = -1;
- if (POLLNVAL & revents) op->syserrno = EBADF;
- else if (POLLHUP & revents) op->syserrno = EPIPE;
- (void)pt_FinishTimedInternal(op);
- if (op == my_op) goto recycle;
- PR_Unlock(tqp->ml);
- }
- else if ((0 != (revents & op->fd->secret->eventMask[io_tq_index]))
- && (pt_continuation_pending == op->status))
- {
- /*
- * Only good?(?) revents left. Operations not pending
- * will be pruned next time we build a list. This operation
- * will be pruned if the continuation indicates it is
- * finished.
- */
-
- if (op->function(op, revents))
- {
- PR_Lock(tqp->ml);
- (void)pt_FinishTimedInternal(op);
- if (op == my_op) goto recycle;
- PR_Unlock(tqp->ml);
- }
- else
- {
- /*
- * If the continuation function returns
- * PR_FALSE, it means available data have
- * been read, output buffer space has been
- * filled, or pending connections have been
- * accepted by prior calls. If the
- * continuation function is immediately
- * invoked again, it will most likely
- * return PR_FALSE. So turn off these
- * events in the event mask for this fd so
- * that if this fd is encountered again in
- * the polling list with these events on,
- * we won't invoke the continuation
- * function again.
- */
- op->fd->secret->eventMask[io_tq_index] &= ~revents;
- }
- }
- }
- }
-
- /*
- * This is timeout processing. It is done after checking
- * for good completions. Those that just made it under the
- * wire are lucky, but none the less, valid.
- */
- now = PR_IntervalNow();
- PR_Lock(tqp->ml);
- while ((NULL != tqp->head)
- && (PR_INTERVAL_NO_TIMEOUT != tqp->head->timeout))
- {
- op = tqp->head; /* get a copy of this before finishing it */
- if ((PRInt32)(op->absolute - now) > 0) break;
- /*
- * The head element of the timed queue has timed out. Record
- * the reason for completion and take it out of the list.
- */
- op->result.code = -1;
- op->syserrno = ETIMEDOUT;
- (void)pt_FinishTimedInternal(op);
-
- /*
- * If it's 'my_op' then we have to switch threads. Exit w/o
- * finishing the scan. The scan will be completed when another
- * thread calls in acting as the continuation thread.
- */
- if (op == my_op) goto recycle; /* exit w/o unlocking */
- }
- PR_Unlock(tqp->ml);
- }
-
- PR_NOT_REACHED("This is a while(true) loop /w no breaks");
-
-recycle:
- /*
- ** Recycling the continuation thread.
- **
- ** The thread we were using for I/O continuations just completed
- ** the I/O it submitted. It has to return to it's caller. We need
- ** another thread to act in the continuation role. We can do that
- ** by taking any operation off the timed queue, setting its state
- ** to 'recycle' and notifying the condition.
- **
- ** Selecting a likely thread seems like magic. I'm going to try
- ** using one that has the longest (or no) timeout, tqp->tail.
- ** If that slot's empty, then there's no outstanding I/O and we
- ** don't need a thread at all.
- **
- ** BTW, we're locked right now, and we'll be returning with the
- ** the lock held as well. Seems odd, doesn't it?
- */
-
- /* $$$ should this be called with the lock held? $$$ */
- PR_SetThreadPriority(tqp->thread, priority); /* reset back to caller's */
-
- PR_ASSERT((NULL == tqp->head) == (0 == tqp->op_count));
- PR_ASSERT((NULL == tqp->head) == (NULL == tqp->tail));
- PR_ASSERT(pt_continuation_done == my_op->status);
+ PRInt32 msecs;
+ PRIntervalTime epoch, now, elapsed, remaining;
+ PRThread *self = PR_GetCurrentThread();
- if (NULL != tqp->tail)
- {
- if (tqp->tail->status != pt_continuation_abort)
- {
- tqp->tail->status = pt_continuation_recycle;
- }
- PR_NotifyCondVar(tqp->tail->complete);
-#if defined(DEBUG)
- pt_debug.recyclesNeeded += 1;
-#endif
- }
-#if defined(DEBUG)
- else pt_debug.quiescentIO += 1;
-#endif
-
-} /* pt_ContinuationThreadInternal */
+ PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout);
+
+ 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 (self->state & PT_THREAD_ABORTED)
+ {
+ 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;
+
+ msecs = (PRInt32)PR_IntervalToMilliseconds(remaining);
+ if (msecs > PT_DEFAULT_POLL_MSEC)
+ msecs = PT_DEFAULT_POLL_MSEC;
+ rv = poll(&tmp_pfd, 1, msecs);
+
+ if (self->state & PT_THREAD_ABORTED)
+ {
+ 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 */
+ 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)
{
- PRStatus rv;
- PRThread *self = PR_GetCurrentThread();
- struct pt_TimedQueue *tqp;
-
- /* lazy assignment of the thread's ioq */
- if (-1 == self->io_tq_index)
- {
- self->io_tq_index = (PR_AtomicIncrement(&_pt_tq_index)-1) % _pt_tq_count;
- }
-
- PR_ASSERT(self->io_tq_index >= 0);
- tqp = &pt_tqp[self->io_tq_index];
-
- /* lazy allocation of the thread's cv */
- if (NULL == self->io_cv)
- self->io_cv = PR_NewCondVar(tqp->ml);
- /* Finish filling in the blank slots */
- op->complete = self->io_cv;
op->status = pt_continuation_pending; /* set default value */
- op->io_tq_index = self->io_tq_index;
- PR_Lock(tqp->ml); /* we provide the locking */
-
- pt_InsertTimedInternal(op); /* insert in the structure */
-
- /*
- ** At this point, we try to decide whether there is a continuation
- ** thread, or whether we should assign this one to serve in that role.
- */
- do
- {
- if (NULL == tqp->thread)
- {
- /*
- ** We're the one. Call the processing function with the lock
- ** held. It will return with it held as well, though there
- ** will certainly be times within the function when it gets
- ** released.
- */
- tqp->thread = self; /* I'm taking control */
- pt_ContinuationThreadInternal(op); /* go slash and burn */
- PR_ASSERT(pt_continuation_done == op->status);
- tqp->thread = NULL; /* I'm abdicating my rule */
- }
- else
- {
- 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
- * irritate him. He's cycling around at least every mx_poll_ticks
- * anyhow and should notice the request in there. When he does
- * notice, this operation will be finished and the op's status
- * marked as pt_continuation_done.
- */
- if ((PR_FAILURE == rv) /* the wait was interrupted */
- && (PR_PENDING_INTERRUPT_ERROR == PR_GetError()))
- {
- if (pt_continuation_done == op->status)
- {
- /*
- * The op is done and has been removed
- * from the timed queue. We must not
- * change op->status, otherwise this
- * thread will go around the loop again.
- *
- * It's harsh to mark the op failed with
- * interrupt error when the io is already
- * done, but we should indicate the fact
- * that the thread was interrupted. So
- * we set the aborted flag to abort the
- * thread's next blocking call. Is this
- * the right thing to do?
- */
- self->state |= PT_THREAD_ABORTED;
- }
- else
- {
- /* go around the loop again */
- op->status = pt_continuation_abort;
- }
- }
- /*
- * If we're to recycle, continue within this loop. This will
- * cause this thread to become the continuation thread.
- */
-
- }
- } while (pt_continuation_done != op->status);
-
-
- PR_Unlock(tqp->ml); /* we provided the locking */
-
- return op->result.code; /* and the primary answer */
+ /*
+ * let each thread call poll directly
+ */
+ pt_poll_now(op);
+ PR_ASSERT(pt_continuation_done == op->status);
+ return op->result.code;
} /* pt_Continue */
/*****************************************************************************/
@@ -1290,52 +749,8 @@ static PRBool pt_hpux_sendfile_cont(pt_Continuation *op, PRInt16 revents)
}
#endif /* HPUX11 */
-#define _MD_CPUS_ONLINE 2
-
void _PR_InitIO()
{
- PRIntn index;
- char *num_io_queues;
-
- if (NULL != (num_io_queues = getenv("NSPR_NUM_IO_QUEUES")))
- {
- _pt_tq_count = atoi(num_io_queues);
- }
- else
- {
- /*
- * Get the number of CPUs if the pthread
- * library has kernel-scheduled entities that
- * can run on multiple CPUs.
- */
-#ifdef HPUX11
- _pt_num_cpus = pthread_num_processors_np();
-#elif defined(IRIX) || defined(OSF1)
- _pt_num_cpus = sysconf(_SC_NPROC_ONLN);
-#elif defined(AIX) || defined(LINUX) || defined(SOLARIS)
- _pt_num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
-#else
- /*
- * A pure user-level (Mx1) pthread library can
- * only use one CPU, even on a multiprocessor.
- */
- _pt_num_cpus = 1;
-#endif
- if (_pt_num_cpus < 0)
- _pt_num_cpus = _MD_CPUS_ONLINE;
- _pt_tq_count = _pt_num_cpus;
- }
-
- pt_tqp = (struct pt_TimedQueue *)
- PR_CALLOC(_pt_tq_count * sizeof(struct pt_TimedQueue));
- PR_ASSERT(NULL != pt_tqp);
-
- for (index = 0; index < _pt_tq_count; index++)
- {
- pt_tqp[index].ml = PR_NewLock();
- PR_ASSERT(NULL != pt_tqp[index].ml);
- }
-
#if defined(DEBUG)
memset(&pt_debug, 0, sizeof(PTDebug));
pt_debug.timeStarted = PR_Now();
@@ -1348,10 +763,11 @@ void _PR_InitIO()
_PR_InitFdCache(); /* do that */
- _pr_stdin = pt_SetMethods(0, PR_DESC_FILE);
- _pr_stdout = pt_SetMethods(1, PR_DESC_FILE);
- _pr_stderr = pt_SetMethods(2, PR_DESC_FILE);
+ _pr_stdin = pt_SetMethods(0, PR_DESC_FILE, PR_FALSE);
+ _pr_stdout = pt_SetMethods(1, PR_DESC_FILE, PR_FALSE);
+ _pr_stderr = pt_SetMethods(2, PR_DESC_FILE, PR_FALSE);
PR_ASSERT(_pr_stdin && _pr_stdout && _pr_stderr);
+
} /* _PR_InitIO */
PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd)
@@ -1438,7 +854,6 @@ static PRInt32 pt_Read(PRFileDesc *fd, void *buf, PRInt32 amount)
&& (!fd->secret->nonblocking))
{
pt_Continuation op;
- op.fd = fd;
op.arg1.osfd = fd->secret->md.osfd;
op.arg2.buffer = buf;
op.arg3.amount = amount;
@@ -1479,7 +894,6 @@ static PRInt32 pt_Write(PRFileDesc *fd, const void *buf, PRInt32 amount)
if (fNeedContinue == PR_TRUE)
{
pt_Continuation op;
- op.fd = fd;
op.arg1.osfd = fd->secret->md.osfd;
op.arg2.buffer = (void*)buf;
op.arg3.amount = amount;
@@ -1573,7 +987,6 @@ static PRInt32 pt_Writev(
{
pt_Continuation op;
- op.fd = fd;
op.arg1.osfd = fd->secret->md.osfd;
op.arg2.buffer = (void*)osiov;
op.arg3.amount = osiov_len;
@@ -1690,7 +1103,9 @@ static PRStatus pt_Connect(
{
PRIntn rv = -1, syserrno;
pt_SockLen addr_len;
-#ifdef _PR_HAVE_SOCKADDR_LEN
+ const PRNetAddr *addrp = addr;
+#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
+ PRUint16 md_af = addr->raw.family;
PRNetAddr addrCopy;
#endif
@@ -1698,13 +1113,24 @@ static PRStatus pt_Connect(
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 = addr->raw.family;
+ ((struct sockaddr*)&addrCopy)->sa_family = md_af;
rv = connect(fd->secret->md.osfd, (struct sockaddr*)&addrCopy, addr_len);
#else
- rv = connect(fd->secret->md.osfd, (struct sockaddr*)addr, addr_len);
+ rv = connect(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len);
#endif
syserrno = errno;
if ((-1 == rv) && (EINPROGRESS == syserrno) && (!fd->secret->nonblocking))
@@ -1713,7 +1139,6 @@ static PRStatus pt_Connect(
else
{
pt_Continuation op;
- op.fd = fd;
op.arg1.osfd = fd->secret->md.osfd;
#ifdef _PR_HAVE_SOCKADDR_LEN
op.arg2.buffer = (void*)&addrCopy;
@@ -1788,7 +1213,6 @@ static PRFileDesc* pt_Accept(
else
{
pt_Continuation op;
- op.fd = fd;
op.arg1.osfd = fd->secret->md.osfd;
op.arg2.buffer = addr;
op.arg3.addr_len = &addr_len;
@@ -1808,7 +1232,11 @@ static PRFileDesc* pt_Accept(
addr->raw.family = ((struct sockaddr*)addr)->sa_family;
}
#endif /* _PR_HAVE_SOCKADDR_LEN */
- newfd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP);
+#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);
if (newfd == NULL) close(osfd); /* $$$ whoops! this doesn't work $$$ */
else
{
@@ -1826,14 +1254,15 @@ static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr)
{
PRIntn rv;
pt_SockLen addr_len;
-#ifdef _PR_HAVE_SOCKADDR_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 */
@@ -1844,14 +1273,25 @@ static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *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
+
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 = addr->raw.family;
+ ((struct sockaddr*)&addrCopy)->sa_family = md_af;
rv = bind(fd->secret->md.osfd, (struct sockaddr*)&addrCopy, addr_len);
#else
- rv = bind(fd->secret->md.osfd, (struct sockaddr*)addr, addr_len);
+ rv = bind(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len);
#endif
if (rv == -1) {
@@ -1919,7 +1359,6 @@ static PRInt32 pt_Recv(
else
{
pt_Continuation op;
- op.fd = fd;
op.arg1.osfd = fd->secret->md.osfd;
op.arg2.buffer = buf;
op.arg3.amount = amount;
@@ -2004,7 +1443,6 @@ static PRInt32 pt_Send(
if (fNeedContinue == PR_TRUE)
{
pt_Continuation op;
- op.fd = fd;
op.arg1.osfd = fd->secret->md.osfd;
op.arg2.buffer = (void*)buf;
op.arg3.amount = amount;
@@ -2034,25 +1472,38 @@ static PRInt32 pt_SendTo(
PRInt32 syserrno, bytes = -1;
PRBool fNeedContinue = PR_FALSE;
pt_SockLen addr_len;
-#ifdef _PR_HAVE_SOCKADDR_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 = addr->raw.family;
+ ((struct sockaddr*)&addrCopy)->sa_family = md_af;
bytes = sendto(
fd->secret->md.osfd, buf, amount, flags,
(struct sockaddr*)&addrCopy, addr_len);
#else
bytes = sendto(
fd->secret->md.osfd, buf, amount, flags,
- (struct sockaddr*)addr, addr_len);
+ (struct sockaddr*)addrp, addr_len);
#endif
syserrno = errno;
if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
@@ -2064,7 +1515,6 @@ static PRInt32 pt_SendTo(
if (fNeedContinue == PR_TRUE)
{
pt_Continuation op;
- op.fd = fd;
op.arg1.osfd = fd->secret->md.osfd;
op.arg2.buffer = (void*)buf;
op.arg3.amount = amount;
@@ -2110,7 +1560,6 @@ static PRInt32 pt_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
if (fNeedContinue == PR_TRUE)
{
pt_Continuation op;
- op.fd = fd;
op.arg1.osfd = fd->secret->md.osfd;
op.arg2.buffer = buf;
op.arg3.amount = amount;
@@ -2132,6 +1581,10 @@ static PRInt32 pt_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
}
}
#endif /* _PR_HAVE_SOCKADDR_LEN */
+#ifdef _PR_INET6
+ if (addr && (AF_INET6 == addr->raw.family))
+ addr->raw.family = PR_AF_INET6;
+#endif
if (bytes < 0)
pt_MapError(_PR_MD_MAP_RECVFROM_ERROR, syserrno);
return bytes;
@@ -2238,7 +1691,6 @@ static PRInt32 pt_AIXSendFile(PRFileDesc *sd, PRSendFileData *sfd,
if ((rv == 1) || ((rv == -1) && (count == 0))) {
pt_Continuation op;
- op.fd = sd;
op.arg1.osfd = sd->secret->md.osfd;
op.arg2.buffer = &sf_struct;
op.arg4.flags = send_flags;
@@ -2357,7 +1809,6 @@ static PRInt32 pt_HPUXSendFile(PRFileDesc *sd, PRSendFileData *sfd,
hdtrl[1].iov_len = sfd->tlen - trailer_nbytes_sent;
}
- op.fd = sd;
op.arg1.osfd = sd->secret->md.osfd;
op.filedesc = sfd->fd->secret->md.osfd;
op.arg2.buffer = hdtrl;
@@ -2503,6 +1954,10 @@ static PRStatus pt_GetSockName(PRFileDesc *fd, PRNetAddr *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;
@@ -2530,113 +1985,16 @@ static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *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_GetSockOpt(
- PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen)
-{
- PRIntn rv = -1;
- PRInt32 level, name;
-
- if (pt_TestAbort()) return PR_FAILURE;
-
- /*
- * PR_SockOpt_Nonblocking is a special case that does not
- * translate to a getsockopt() call.
- */
- if (PR_SockOpt_Nonblocking == optname)
- {
- PR_ASSERT(sizeof(PRIntn) <= *optlen);
- *((PRIntn *) optval) = (PRIntn) fd->secret->nonblocking;
- *optlen = sizeof(PRIntn);
- return PR_SUCCESS;
- }
-
- rv = _PR_MapOptionName(optname, &level, &name);
- if (0 == rv)
- {
- if (PR_SockOpt_Linger == optname)
- {
- struct linger linger;
- pt_SockLen len = sizeof(linger);
- rv = getsockopt(fd->secret->md.osfd, level, name,
- (char *) &linger, &len);
- if (0 == rv)
- {
- ((PRLinger*)(optval))->polarity = linger.l_onoff
- ? PR_TRUE : PR_FALSE;
- ((PRLinger*)(optval))->linger = PR_SecondsToInterval(
- linger.l_linger);
- *optlen = sizeof(PRLinger);
- }
- }
- else
- {
- /* Make sure the pointer type cast below is safe */
- PR_ASSERT(sizeof(PRInt32) == sizeof(PRIntn));
- rv = getsockopt(fd->secret->md.osfd, level, name,
- optval, (pt_SockLen*)optlen);
- }
- }
-
- if (rv == -1) {
- pt_MapError(_PR_MD_MAP_GETSOCKOPT_ERROR, errno);
- return PR_FAILURE;
- } else {
- return PR_SUCCESS;
- }
-} /* pt_GetSockOpt */
-
-static PRStatus pt_SetSockOpt(
- PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen)
-{
- PRIntn rv = -1;
- PRInt32 level, name;
-
- if (pt_TestAbort()) return PR_FAILURE;
-
- /*
- * PR_SockOpt_Nonblocking is a special case that does not
- * translate to a setsockopt() call.
- */
- if (PR_SockOpt_Nonblocking == optname)
- {
- PR_ASSERT(sizeof(PRIntn) == optlen);
- fd->secret->nonblocking = *((PRIntn *) optval) ? PR_TRUE : PR_FALSE;
- return PR_SUCCESS;
- }
-
- rv = _PR_MapOptionName(optname, &level, &name);
- if (0 == rv)
- {
- if (PR_SockOpt_Linger == optname)
- {
- struct linger linger;
- linger.l_onoff = ((PRLinger*)(optval))->polarity;
- linger.l_linger = PR_IntervalToSeconds(
- ((PRLinger*)(optval))->linger);
- rv = setsockopt(fd->secret->md.osfd, level, name,
- (char *) &linger, sizeof(linger));
- }
- else
- {
- rv = setsockopt(fd->secret->md.osfd, level, name,
- optval, optlen);
- }
- }
-
- if (rv == -1) {
- pt_MapError(_PR_MD_MAP_SETSOCKOPT_ERROR, errno);
- return PR_FAILURE;
- } else {
- return PR_SUCCESS;
- }
-} /* pt_SetSockOpt */
-
static PRStatus pt_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
{
PRIntn rv;
@@ -2896,8 +2254,8 @@ static PRIOMethods _pr_file_methods = {
(PRTransmitfileFN)_PR_InvalidInt,
(PRGetsocknameFN)_PR_InvalidStatus,
(PRGetpeernameFN)_PR_InvalidStatus,
- (PRGetsockoptFN)_PR_InvalidStatus,
- (PRSetsockoptFN)_PR_InvalidStatus,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
@@ -2935,8 +2293,8 @@ static PRIOMethods _pr_pipe_methods = {
(PRTransmitfileFN)_PR_InvalidInt,
(PRGetsocknameFN)_PR_InvalidStatus,
(PRGetpeernameFN)_PR_InvalidStatus,
- (PRGetsockoptFN)_PR_InvalidStatus,
- (PRSetsockoptFN)_PR_InvalidStatus,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
@@ -2974,8 +2332,8 @@ static PRIOMethods _pr_tcp_methods = {
pt_TransmitFile,
pt_GetSockName,
pt_GetPeerName,
- pt_GetSockOpt,
- pt_SetSockOpt,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
pt_GetSocketOption,
pt_SetSocketOption,
pt_SendFile,
@@ -3013,8 +2371,8 @@ static PRIOMethods _pr_udp_methods = {
(PRTransmitfileFN)_PR_InvalidInt,
pt_GetSockName,
pt_GetPeerName,
- pt_GetSockOpt,
- pt_SetSockOpt,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
pt_GetSocketOption,
pt_SetSocketOption,
(PRSendfileFN)_PR_InvalidInt,
@@ -3025,7 +2383,6 @@ static PRIOMethods _pr_udp_methods = {
(PRReservedFN)_PR_InvalidInt
};
-
static PRIOMethods _pr_socketpollfd_methods = {
(PRDescType) 0,
(PRCloseFN)_PR_InvalidStatus,
@@ -3053,8 +2410,8 @@ static PRIOMethods _pr_socketpollfd_methods = {
(PRTransmitfileFN)_PR_InvalidInt,
(PRGetsocknameFN)_PR_InvalidStatus,
(PRGetpeernameFN)_PR_InvalidStatus,
- (PRGetsockoptFN)_PR_InvalidStatus,
- (PRSetsockoptFN)_PR_InvalidStatus,
+ (PRReservedFN)_PR_InvalidInt,
+ (PRReservedFN)_PR_InvalidInt,
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
@@ -3065,10 +2422,6 @@ static PRIOMethods _pr_socketpollfd_methods = {
(PRReservedFN)_PR_InvalidInt
};
-#if defined(_PR_FCNTL_FLAGS)
-#undef _PR_FCNTL_FLAGS
-#endif
-
#if defined(HPUX) || defined(OSF1) || defined(SOLARIS) || defined (IRIX) \
|| defined(AIX) || defined(LINUX) || defined(FREEBSD) || defined(NETBSD) \
|| defined(OPENBSD) || defined(BSDI) || defined(VMS) || defined(NTO)
@@ -3077,9 +2430,58 @@ static PRIOMethods _pr_socketpollfd_methods = {
#error "Can't determine architecture"
#endif
-static PRFileDesc *pt_SetMethods(PRIntn osfd, PRDescType type)
+/*
+ * 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
+
+#ifdef DEBUG
+static void pt_AssertCloseOnExecIsCleared(PRIntn osfd)
+{
+ /*
+ * Ignore EBADF error on fd's 0, 1, 2 because they are
+ * not open in all processes.
+ */
+ PRIntn flags;
+ flags = fcntl(osfd, F_GETFD, 0);
+ PR_ASSERT((0 == flags) || (-1 == flags
+ && (0 <= osfd && osfd <= 2) && errno == EBADF));
+}
+#endif
+
+static PRFileDesc *pt_SetMethods(
+ PRIntn osfd, PRDescType type, PRBool isAcceptedSocket)
{
- PRInt32 flags;
PRFileDesc *fd = _PR_Getfd();
if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
@@ -3089,13 +2491,7 @@ static PRFileDesc *pt_SetMethods(PRIntn osfd, PRDescType type)
fd->secret->state = _PR_FILEDESC_OPEN;
/* By default, a Unix fd is not closed on exec. */
#ifdef DEBUG
- /*
- * Ignore EBADF error on fd's 0, 1, 2 because they are
- * not open in all processes.
- */
- flags = fcntl(osfd, F_GETFD, 0);
- PR_ASSERT((0 == flags) || (-1 == flags
- && (0 <= osfd && osfd <= 2) && errno == EBADF));
+ pt_AssertCloseOnExecIsCleared(osfd);
#endif
fd->secret->inheritable = PR_TRUE;
switch (type)
@@ -3105,18 +2501,19 @@ static PRFileDesc *pt_SetMethods(PRIntn osfd, PRDescType type)
break;
case PR_DESC_SOCKET_TCP:
fd->methods = PR_GetTCPMethods();
- flags = fcntl(osfd, F_GETFL, 0);
- flags |= _PR_FCNTL_FLAGS;
- (void)fcntl(osfd, F_SETFL, flags);
+#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();
- flags = fcntl(osfd, F_GETFL, 0);
- flags |= _PR_FCNTL_FLAGS;
- (void)fcntl(osfd, F_SETFL, flags);
+ pt_MakeFdNonblock(osfd);
break;
case PR_DESC_PIPE:
fd->methods = PR_GetPipeMethods();
+ pt_MakeFdNonblock(osfd);
break;
default:
break;
@@ -3168,13 +2565,14 @@ PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
if (osfd > 2)
{
/* Don't mess around with stdin, stdout or stderr */
- PRIntn flags;
- flags = fcntl(osfd, F_GETFL, 0);
- fcntl(osfd, F_SETFL, flags | _PR_FCNTL_FLAGS);
+ if (&_pr_tcp_methods == methods) pt_MakeSocketNonblock(osfd);
+ else pt_MakeFdNonblock(osfd);
}
fd->secret->state = _PR_FILEDESC_OPEN;
/* By default, a Unix fd is not closed on exec. */
- PR_ASSERT(0 == fcntl(osfd, F_GETFD, 0));
+#ifdef DEBUG
+ pt_AssertCloseOnExecIsCleared(osfd);
+#endif
fd->secret->inheritable = PR_TRUE;
return fd;
@@ -3183,40 +2581,91 @@ failed:
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)
+PR_EXTERN(PRBool) _pr_ipv6_is_present;
+PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket()
+{
+PRInt32 osfd;
+
+ 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
-#if defined(_PR_INET6)
- && PF_INET6 != domain
-#endif
+ && 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 (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)
+ if (PR_AF_INET6 == domain) {
+#if defined(_PR_INET6_PROBE)
+ if (_pr_ipv6_is_present == PR_FALSE)
+ domain = AF_INET;
+ else
+#endif
+ domain = AF_INET6;
+ }
+#elif defined(_PR_INET6_PROBE)
+ if (PR_AF_INET6 == domain) {
+ if (_pr_ipv6_is_present == PR_FALSE)
+ domain = AF_INET;
+ else
+ domain = AF_INET6;
+ }
+#else
+ if (PR_AF_INET6 == domain)
+ domain = AF_INET;
+#endif
osfd = socket(domain, type, proto);
if (osfd == -1) pt_MapError(_PR_MD_MAP_SOCKET_ERROR, errno);
else
{
- fd = pt_SetMethods(osfd, ftype);
+ fd = pt_SetMethods(osfd, ftype, PR_FALSE);
if (fd == NULL) close(osfd);
}
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+ 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 */
@@ -3224,7 +2673,8 @@ PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
/****************************** I/O public methods ***************************/
/*****************************************************************************/
-PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)
+PR_IMPLEMENT(PRFileDesc*) PR_OpenFile(
+ const char *name, PRIntn flags, PRIntn mode)
{
PRFileDesc *fd = NULL;
PRIntn syserrno, osfd = -1, osflags = 0;;
@@ -3238,6 +2688,17 @@ PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)
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
@@ -3261,10 +2722,15 @@ PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)
pt_MapError(_PR_MD_MAP_OPEN_ERROR, syserrno);
else
{
- fd = pt_SetMethods(osfd, PR_DESC_FILE);
+ fd = pt_SetMethods(osfd, PR_DESC_FILE, 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)
@@ -3371,7 +2837,7 @@ PR_IMPLEMENT(PRStatus) PR_CloseDir(PRDir *dir)
return PR_SUCCESS;
} /* PR_CloseDir */
-PR_IMPLEMENT(PRStatus) PR_MkDir(const char *name, PRIntn mode)
+PR_IMPLEMENT(PRStatus) PR_MakeDir(const char *name, PRIntn mode)
{
PRInt32 rv = -1;
@@ -3390,6 +2856,11 @@ PR_IMPLEMENT(PRStatus) PR_MkDir(const char *name, PRIntn mode)
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)
@@ -3694,10 +3165,6 @@ PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket()
{
PRIntn domain = PF_INET;
-#if defined(_PR_INET6)
- if (_pr_ipv6_enabled)
- domain = PF_INET6;
-#endif
return PR_Socket(domain, SOCK_DGRAM, 0);
} /* PR_NewUDPSocket */
@@ -3705,10 +3172,6 @@ PR_IMPLEMENT(PRFileDesc*) PR_NewTCPSocket()
{
PRIntn domain = PF_INET;
-#if defined(_PR_INET6)
- if (_pr_ipv6_enabled)
- domain = PF_INET6;
-#endif
return PR_Socket(domain, SOCK_STREAM, 0);
} /* PR_NewTCPSocket */
@@ -3733,13 +3196,13 @@ PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *fds[2])
return PR_FAILURE;
}
- fds[0] = pt_SetMethods(osfd[0], PR_DESC_SOCKET_TCP);
+ fds[0] = pt_SetMethods(osfd[0], PR_DESC_SOCKET_TCP, 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);
+ fds[1] = pt_SetMethods(osfd[1], PR_DESC_SOCKET_TCP, PR_FALSE);
if (fds[1] == NULL) {
PR_Close(fds[0]);
close(osfd[1]);
@@ -3754,7 +3217,6 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
)
{
int pipefd[2];
- int flags;
if (pt_TestAbort()) return PR_FAILURE;
@@ -3764,26 +3226,20 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
PR_SetError(PR_UNKNOWN_ERROR, errno);
return PR_FAILURE;
}
- *readPipe = pt_SetMethods(pipefd[0], PR_DESC_PIPE);
+ *readPipe = pt_SetMethods(pipefd[0], PR_DESC_PIPE, PR_FALSE);
if (NULL == *readPipe)
{
close(pipefd[0]);
close(pipefd[1]);
return PR_FAILURE;
}
- flags = fcntl(pipefd[0], F_GETFL, 0);
- flags |= _PR_FCNTL_FLAGS;
- (void)fcntl(pipefd[0], F_SETFL, flags);
- *writePipe = pt_SetMethods(pipefd[1], PR_DESC_PIPE);
+ *writePipe = pt_SetMethods(pipefd[1], PR_DESC_PIPE, PR_FALSE);
if (NULL == *writePipe)
{
PR_Close(*readPipe);
close(pipefd[1]);
return PR_FAILURE;
}
- flags = fcntl(pipefd[1], F_GETFL, 0);
- flags |= _PR_FCNTL_FLAGS;
- (void)fcntl(pipefd[1], F_SETFL, flags);
return PR_SUCCESS;
}
@@ -3824,7 +3280,7 @@ PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PRInt32 osfd)
PRFileDesc *fd;
if (!_pr_initialized) _PR_ImplicitInitialization();
- fd = pt_SetMethods(osfd, PR_DESC_FILE);
+ fd = pt_SetMethods(osfd, PR_DESC_FILE, PR_FALSE);
if (NULL == fd) close(osfd);
return fd;
} /* PR_ImportFile */
@@ -3834,7 +3290,7 @@ PR_IMPLEMENT(PRFileDesc*) PR_ImportTCPSocket(PRInt32 osfd)
PRFileDesc *fd;
if (!_pr_initialized) _PR_ImplicitInitialization();
- fd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP);
+ fd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_FALSE);
if (NULL == fd) close(osfd);
return fd;
} /* PR_ImportTCPSocket */
@@ -3844,7 +3300,7 @@ PR_IMPLEMENT(PRFileDesc*) PR_ImportUDPSocket(PRInt32 osfd)
PRFileDesc *fd;
if (!_pr_initialized) _PR_ImplicitInitialization();
- fd = pt_SetMethods(osfd, PR_DESC_SOCKET_UDP);
+ fd = pt_SetMethods(osfd, PR_DESC_SOCKET_UDP, PR_FALSE);
if (NULL != fd) close(osfd);
return fd;
} /* PR_ImportUDPSocket */
diff --git a/pr/src/pthreads/ptsynch.c b/pr/src/pthreads/ptsynch.c
index 0731786e..b3ff68da 100644
--- a/pr/src/pthreads/ptsynch.c
+++ b/pr/src/pthreads/ptsynch.c
@@ -761,7 +761,7 @@ PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name)
* From the semctl(2) man page in glibc 2.0
*/
#if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) \
- || defined(FREEBSD) || defined(OPENBSD)
+ || defined(FREEBSD) || defined(OPENBSD) || defined(BSDI)
/* union semun is defined by including <sys/sem.h> */
#else
/* according to X/OPEN we have to define it ourselves */
diff --git a/pr/src/pthreads/ptthread.c b/pr/src/pthreads/ptthread.c
index 8e81c202..23189c53 100644
--- a/pr/src/pthreads/ptthread.c
+++ b/pr/src/pthreads/ptthread.c
@@ -158,16 +158,6 @@ static void *_pt_root(void *arg)
/* unhook the thread from the runtime */
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);
- thred->prev->next = thred->next;
- if (NULL == thred->next)
- pt_book.last = thred->prev;
- else
- thred->next->prev = thred->prev;
-
/*
* At this moment, PR_CreateThread() may not have set thred->id yet.
* It is safe for a detached thread to free thred only after
@@ -178,6 +168,16 @@ static void *_pt_root(void *arg)
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);
+ 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);
/*
@@ -224,7 +224,6 @@ static PRThread* pt_AttachThread(void)
PR_ASSERT(0 == rv);
thred->state = PT_THREAD_GLOBAL | PT_THREAD_FOREIGN;
- thred->io_tq_index = -1;
PR_Lock(pt_book.ml);
/* then put it into the list */
@@ -363,8 +362,6 @@ static PRThread* _PR_CreateThread(
thred->stack->stackSize = stackSize;
thred->stack->thr = thred;
- thred->io_tq_index = -1;
-
#ifdef PT_NO_SIGTIMEDWAIT
pthread_mutex_init(&thred->suspendResumeMutex,NULL);
pthread_cond_init(&thred->suspendResumeCV,NULL);
@@ -740,8 +737,6 @@ static void _pt_thread_death(void *arg)
PR_Free(thred->privateData);
if (NULL != thred->errorString)
PR_Free(thred->errorString);
- if (NULL != thred->io_cv)
- PR_DestroyCondVar(thred->io_cv);
PR_Free(thred->stack);
#if defined(DEBUG)
memset(thred, 0xaf, sizeof(PRThread));
@@ -807,8 +802,6 @@ void _PR_InitThreads(
thred->stack->thr = thred;
_PR_InitializeStack(thred->stack);
- thred->io_tq_index = -1;
-
/*
* Create a key for our use to store a backpointer in the pthread
* to our PRThread object. This object gets deleted when the thread
diff --git a/pr/tests/Makefile b/pr/tests/Makefile
index 7bf967f6..d1851723 100644
--- a/pr/tests/Makefile
+++ b/pr/tests/Makefile
@@ -39,6 +39,7 @@ endif
CSRCS = \
accept.c \
acceptread.c \
+ addrstr.c \
affinity.c \
alarm.c \
anonfm.c \
@@ -83,6 +84,8 @@ CSRCS = \
lock.c \
lockfile.c \
logger.c \
+ makedir.c \
+ mbcs.c \
multiacc.c \
multiwait.c \
many_cv.c \
@@ -91,12 +94,14 @@ CSRCS = \
nblayer.c \
nonblock.c \
ntioto.c \
+ ntoh.c \
op_2long.c \
op_excl.c \
op_filnf.c \
op_filok.c \
op_noacc.c \
op_nofil.c \
+ openfile.c \
parent.c \
perf.c \
pipeping.c \
diff --git a/pr/tests/Makefile.in b/pr/tests/Makefile.in
index 9d6a0de9..720dc68a 100644
--- a/pr/tests/Makefile.in
+++ b/pr/tests/Makefile.in
@@ -44,6 +44,7 @@ endif
CSRCS = \
accept.c \
acceptread.c \
+ addrstr.c \
affinity.c \
alarm.c \
anonfm.c \
@@ -88,6 +89,7 @@ CSRCS = \
lock.c \
lockfile.c \
logger.c \
+ makedir.c \
multiacc.c \
multiwait.c \
many_cv.c \
@@ -96,12 +98,14 @@ CSRCS = \
nblayer.c \
nonblock.c \
ntioto.c \
+ ntoh.c \
op_2long.c \
op_excl.c \
op_filnf.c \
op_filok.c \
op_noacc.c \
op_nofil.c \
+ openfile.c \
parent.c \
perf.c \
pipeping.c \
diff --git a/pr/tests/accept.c b/pr/tests/accept.c
index e2fb0a05..1b64b5bd 100644
--- a/pr/tests/accept.c
+++ b/pr/tests/accept.c
@@ -84,7 +84,7 @@ static PRNetAddr listenAddr;
static PRNetAddr clientAddr;
static PRThread *clientThread;
static PRNetAddr *raddr;
-static char buf[4096 + 64];
+static char buf[4096 + 2*sizeof(PRNetAddr) + 32];
static PRInt32 status;
static PRInt32 bytesRead;
diff --git a/pr/tests/acceptread.c b/pr/tests/acceptread.c
index d24e93c1..a6b257db 100644
--- a/pr/tests/acceptread.c
+++ b/pr/tests/acceptread.c
@@ -105,7 +105,7 @@ static void AcceptingThread(void *arg)
PRStatus rv;
PRInt32 bytes;
PRSize buf_size = BUF_SIZE;
- PRUint8 buf[BUF_SIZE + (20 * sizeof(PRNetAddr))];
+ 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;
diff --git a/pr/tests/addrstr.c b/pr/tests/addrstr.c
new file mode 100644
index 00000000..a20065e2
--- /dev/null
+++ b/pr/tests/addrstr.c
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 2000 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#include "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()
+{
+ 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/pr/tests/affinity.c b/pr/tests/affinity.c
index fa0f5acb..c0609b19 100644
--- a/pr/tests/affinity.c
+++ b/pr/tests/affinity.c
@@ -17,6 +17,7 @@
*/
#include "nspr.h"
+#include "pprthred.h"
#include "plgetopt.h"
#include <stdio.h>
diff --git a/pr/tests/cltsrv.c b/pr/tests/cltsrv.c
index f19995c7..7c5becc0 100644
--- a/pr/tests/cltsrv.c
+++ b/pr/tests/cltsrv.c
@@ -83,7 +83,7 @@
#define DEFAULT_HIGH 0
#define BUFFER_SIZE 1024
#define DEFAULT_BACKLOG 5
-#define DEFAULT_PORT 12848
+#define DEFAULT_PORT 12849
#define DEFAULT_CLIENTS 1
#define ALLOWED_IN_ACCEPT 1
#define DEFAULT_CLIPPING 1000
@@ -773,8 +773,11 @@ static void PR_CALLBACK Server(void *arg)
TEST_ASSERT(PR_SUCCESS == rv);
memset(&serverAddress, 0, sizeof(serverAddress));
- rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &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);
@@ -888,9 +891,7 @@ static void Help(void)
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");
-#ifdef _PR_INET6
PR_fprintf(debug_out, "\t-6 Use IPv6 (IPv4)\n");
-#endif /* _PR_INET6 */
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");
@@ -951,12 +952,9 @@ PRIntn main(PRIntn argc, char** argv)
case 'X': /* use XTP as transport */
protocol = 36;
break;
-#ifdef _PR_INET6
- case '6': /* Use IPv6 */
- domain = AF_INET6;
- PR_SetIPv6Enable(PR_TRUE);
+ case '6': /* Use IPv6 */
+ domain = PR_AF_INET6;
break;
-#endif /* _PR_INET6 */
case 'a': /* the value for accepting */
accepting = atoi(opt->value);
break;
@@ -1097,9 +1095,13 @@ PRIntn main(PRIntn argc, char** argv)
client[index].ml = PR_NewLock();
if (serverIsLocal)
{
- (void)PR_InitializeNetAddr(
- PR_IpAddrLoopback, DEFAULT_PORT,
- &client[index].serverAddress);
+ 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
{
diff --git a/pr/tests/gethost.c b/pr/tests/gethost.c
index 9b13b9c7..7a611981 100644
--- a/pr/tests/gethost.c
+++ b/pr/tests/gethost.c
@@ -35,8 +35,7 @@
static void Help(void)
{
- fprintf(stderr, "Usage: gethost [-6h] [hostname]\n");
- fprintf(stderr, "\t-6 IPv6 mode (default: FALSE)\n");
+ 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);
@@ -75,17 +74,11 @@ int main(int argc, char **argv)
PRIntn idx;
PRNetAddr addr;
PLOptStatus os;
- PLOptState *opt = PL_CreateOptState(argc, argv, "6h");
+ 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 '6': /* Enable IPv6 */
- if (PR_SetIPv6Enable(PR_TRUE) == PR_FAILURE) {
- fprintf(stderr, "PR_SetIPv6Enable failed\n");
- exit(1);
- }
- break;
case 0: /* naked */
hostName = opt->value;
break;
@@ -126,7 +119,6 @@ int main(int argc, char **argv)
exit(1);
}
PrintHostent(&he);
-#ifdef _PR_INET6
printf("PR_GetIPNodeByName with PR_AF_INET6\n");
if (PR_GetIPNodeByName(hostName, PR_AF_INET6, PR_AI_DEFAULT,
buf, sizeof(buf), &he) == PR_FAILURE) {
@@ -134,10 +126,49 @@ int main(int argc, char **argv)
exit(1);
}
PrintHostent(&he);
-#endif
-
+ 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");
@@ -180,6 +211,11 @@ int main(int argc, char **argv)
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);
@@ -187,8 +223,12 @@ int main(int argc, char **argv)
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 defined(_PR_INET6)
if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
fprintf(stderr, "PR_SetNetAddr failed\n");
exit(1);
@@ -197,6 +237,11 @@ int main(int argc, char **argv)
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);
@@ -205,23 +250,23 @@ int main(int argc, char **argv)
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];
- addr.ipv6.family = PR_AF_INET6;
- addr.ipv6.port = 0;
- addr.ipv6.ip = in6addr_any;
- if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
- fprintf(stderr, "addr should be unspecified address\n");
- exit(1);
- }
- addr.ipv6.family = PR_AF_INET6;
- addr.ipv6.port = 0;
- addr.ipv6.ip = in6addr_loopback;
- if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
- fprintf(stderr, "addr should be loopback address\n");
- exit(1);
- }
-#endif /* _PR_INET6 */
+ 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/pr/tests/ipv6.c b/pr/tests/ipv6.c
index 7e92f3e2..4029fedd 100644
--- a/pr/tests/ipv6.c
+++ b/pr/tests/ipv6.c
@@ -49,10 +49,9 @@ static PRFileDesc *err = NULL;
static void Help(void)
{
- PR_fprintf(err, "Usage: [-V] [-6] [-h]\n");
+ 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-6 First turn on IPv6 capability (default: FALSE)\n");
PR_fprintf(err, "\t-h This message and nothing else\n");
} /* Help */
@@ -106,7 +105,7 @@ PRIntn main(PRIntn argc, char **argv)
PRBool ipv6 = PR_FALSE;
const char *name = NULL;
PRBool failed = PR_FALSE, version = PR_FALSE;
- PLOptState *opt = PL_CreateOptState(argc, argv, "Vh6");
+ PLOptState *opt = PL_CreateOptState(argc, argv, "Vh");
err = PR_GetSpecialFD(PR_StandardError);
@@ -118,9 +117,6 @@ PRIntn main(PRIntn argc, char **argv)
case 0: /* Name of host to lookup */
name = opt->value;
break;
- case '6': /* Turn on IPv6 mode */
- ipv6 = PR_TRUE;
- break;
case 'V': /* Do version discovery */
version = PR_TRUE;
break;
@@ -184,16 +180,6 @@ PRIntn main(PRIntn argc, char **argv)
if (NULL != nspr_name) PR_FreeLibraryName(nspr_name);
}
- if (ipv6)
- {
- rv = PR_SetIPv6Enable(ipv6);
- if (PR_FAILURE == rv)
- {
- failed = PR_TRUE;
- PL_FPrintError(err, "PR_SetIPv6Enable");
- }
- }
-
{
if (NULL == name)
{
@@ -202,7 +188,7 @@ PRIntn main(PRIntn argc, char **argv)
if (PR_FAILURE == rv)
{
failed = PR_TRUE;
- PL_FPrintError(err, "PR_GetHostName");
+ PL_FPrintError(err, "PR_GetSystemInfo");
return 2;
}
name = me; /* just leak the storage */
diff --git a/pr/tests/lltest.c b/pr/tests/lltest.c
index 64e8c3ca..ce0abd89 100644
--- a/pr/tests/lltest.c
+++ b/pr/tests/lltest.c
@@ -80,6 +80,18 @@ 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;
@@ -236,7 +248,55 @@ TestComparisons( void )
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");
@@ -258,7 +318,55 @@ TestComparisons( void )
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;
}
diff --git a/pr/tests/makedir.c b/pr/tests/makedir.c
new file mode 100644
index 00000000..800d5b41
--- /dev/null
+++ b/pr/tests/makedir.c
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 2000 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+/*
+ * 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()
+{
+ 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/pr/tests/mbcs.c b/pr/tests/mbcs.c
new file mode 100644
index 00000000..ffd0974b
--- /dev/null
+++ b/pr/tests/mbcs.c
@@ -0,0 +1,168 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+/*
+** 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() */
+
+PRIntn main(PRIntn 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/pr/tests/nonblock.c b/pr/tests/nonblock.c
index 04475526..223b7a7e 100644
--- a/pr/tests/nonblock.c
+++ b/pr/tests/nonblock.c
@@ -70,7 +70,7 @@ clientThreadFunc(void *arg)
char buf[CHUNK_SIZE];
int i;
PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME);
- PRIntn optval = 1;
+ PRSocketOptionData optval;
PRStatus retVal;
PRInt32 nBytes;
@@ -85,7 +85,9 @@ clientThreadFunc(void *arg)
/* time 1 */
PR_Sleep(unitTime);
sock = PR_NewTCPSocket();
- PR_SetSockOpt(sock, PR_SockOpt_Nonblocking, &optval, sizeof(optval));
+ 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)
@@ -138,7 +140,7 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
char buf[CHUNK_SIZE];
PRThread *clientThread;
PRInt32 retVal;
- PRIntn optval = 1;
+ PRSocketOptionData optval;
PRIntn i;
PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME);
@@ -184,8 +186,9 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
printf("client thread created.\n");
- PR_SetSockOpt(listenSock, PR_SockOpt_Nonblocking, &optval,
- sizeof(PRIntn));
+ 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) {
@@ -208,7 +211,7 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
fflush(stdout);
PR_Close(listenSock);
- PR_SetSockOpt(sock, PR_SockOpt_Nonblocking, &optval, sizeof(PRIntn));
+ PR_SetSocketOption(sock, &optval);
/* time 3, 5, 6, 8, etc. */
for (i = 0; i < NUMBER_ROUNDS; i++) {
diff --git a/pr/tests/ntioto.c b/pr/tests/ntioto.c
index e5c9ecea..7549a436 100644
--- a/pr/tests/ntioto.c
+++ b/pr/tests/ntioto.c
@@ -56,6 +56,7 @@
#include <nspr.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
/*
** Test harness infrastructure
@@ -95,10 +96,17 @@ static void Help( void )
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[100];
+ char dataBuf[ACCEPT_READ_BUFSIZE];
PRFileDesc *arSock;
PRNetAddr *arAddr;
@@ -106,7 +114,7 @@ static void AcceptThread(void *arg)
&arSock,
&arAddr,
dataBuf,
- 10,
+ ACCEPT_READ_DATASIZE,
PR_SecondsToInterval(1));
if ( bytesRead == -1 && PR_GetError() == PR_IO_TIMEOUT_ERROR )
diff --git a/pr/tests/ntoh.c b/pr/tests/ntoh.c
new file mode 100644
index 00000000..006f5b92
--- /dev/null
+++ b/pr/tests/ntoh.c
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 2000 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+/*
+ * A 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()
+{
+ 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/pr/tests/op_excl.c b/pr/tests/op_excl.c
index bfbd33d3..748552a4 100644
--- a/pr/tests/op_excl.c
+++ b/pr/tests/op_excl.c
@@ -118,7 +118,7 @@ PRIntn main(PRIntn argc, char *argv[])
*/
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");
+ if (debug) fprintf( stderr, "Open exclusive. Expected failure, got success\n");
failed_already = 1;
PR_Close(fd);
}
diff --git a/pr/tests/openfile.c b/pr/tests/openfile.c
new file mode 100644
index 00000000..11992c5e
--- /dev/null
+++ b/pr/tests/openfile.c
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 2000 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+/*
+ * 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()
+{
+ 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/pr/tests/poll_nm.c b/pr/tests/poll_nm.c
index 27937b62..65794e34 100644
--- a/pr/tests/poll_nm.c
+++ b/pr/tests/poll_nm.c
@@ -117,7 +117,7 @@ int main(int argc, char **argv)
PRIntn npds;
PRInt32 retVal;
PRIntn i, j;
- PRIntn optval = 1;
+ 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.
@@ -177,7 +177,9 @@ int main(int argc, char **argv)
goto exit_now;
}
listenPort1 = PR_ntohs(addr.inet.port);
- PR_SetSockOpt(listenSock1, PR_SockOpt_Nonblocking, &optval, sizeof(optval));
+ 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;
@@ -203,7 +205,7 @@ int main(int argc, char **argv)
goto exit_now;
}
listenPort2 = PR_ntohs(addr.inet.port);
- PR_SetSockOpt(listenSock2, PR_SockOpt_Nonblocking, &optval, sizeof(optval));
+ PR_SetSocketOption(listenSock2, &optval);
if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
fprintf(stderr, "Can't listen on a socket\n");
failed_already=1;
diff --git a/pr/tests/provider.c b/pr/tests/provider.c
index b2a05283..bec8950a 100644
--- a/pr/tests/provider.c
+++ b/pr/tests/provider.c
@@ -1049,9 +1049,7 @@ static void Help(void)
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");
-#ifdef _PR_INET6
PR_fprintf(debug_out, "\t-6 Use IPv6 (IPv4)\n");
-#endif /* _PR_INET6 */
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");
@@ -1120,12 +1118,9 @@ PRIntn main(PRIntn argc, char** argv)
case 'X': /* use XTP as transport */
protocol = 36;
break;
-#ifdef _PR_INET6
- case '6': /* Use IPv6 */
- domain = AF_INET6;
- PR_SetIPv6Enable(PR_TRUE);
+ case '6': /* Use IPv6 */
+ domain = PR_AF_INET6;
break;
-#endif /* _PR_INET6 */
case 'a': /* the value for accepting */
accepting = atoi(opt->value);
break;
diff --git a/pr/tests/runtests.ksh b/pr/tests/runtests.ksh
index dc5ed319..2e102f52 100755
--- a/pr/tests/runtests.ksh
+++ b/pr/tests/runtests.ksh
@@ -35,11 +35,14 @@ 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
@@ -122,6 +125,7 @@ nameshm1
nblayer
nonblock
ntioto
+ntoh
op_2long
op_excl
op_filnf
@@ -187,36 +191,75 @@ rval=0
# 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`
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"
-for prog in $TESTS
-do
-echo "$prog\c"
-echo "\nBEGIN TEST: $prog\n" >> ${LOGFILE} 2>&1
-export test_rval
-./$prog >> ${LOGFILE} 2>&1 &
-test_pid=$!
-sleep_pid=0
-if [ "$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
- echo "\t\t\tPassed";
+if [ $OS_PLATFORM = "Windows_95" ] || [ $OS_PLATFORM = "Windows_98" ] || [ $OS_PLATFORM = "Windows_NT" ] ; then
+ for prog in $TESTS
+ do
+ echo "$prog\c"
+ echo "\nBEGIN TEST: $prog\n" >> ${LOGFILE} 2>&1
+ ./$prog >> ${LOGFILE} 2>&1
+ if [ 0 = $? ] ; then
+ echo "\t\t\tPassed";
+ else
+ echo "\t\t\tFAILED";
+ rval=1
+ fi;
+ echo "\nEND TEST: $prog\n" >> ${LOGFILE} 2>&1
+ done
else
- echo "\t\t\tFAILED";
- rval=1
+ for prog in $TESTS
+ do
+ echo "$prog\c"
+ echo "\nBEGIN TEST: $prog\n" >> ${LOGFILE} 2>&1
+ export test_rval
+ ./$prog >> ${LOGFILE} 2>&1 &
+ test_pid=$!
+ sleep_pid=0
+ if [ "$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
+ echo "\t\t\tPassed";
+ else
+ echo "\t\t\tFAILED";
+ rval=1
+ fi;
+ echo "\nEND TEST: $prog\n" >> ${LOGFILE} 2>&1
+ done
fi;
-echo "\nEND TEST: $prog\n" >> ${LOGFILE} 2>&1
-done
-echo "END\t\t\t`date`"
+echo "END\t\t\t`date`"
exit $rval
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pr/tests/sema.c b/pr/tests/sema.c
index 4bcc52bd..93f18354 100644
--- a/pr/tests/sema.c
+++ b/pr/tests/sema.c
@@ -52,7 +52,7 @@ void ThreadFunc(void *arg)
}
counter++;
if (PR_PostSemaphore(sem1) == PR_FAILURE) {
- fprintf(stderr, "PR_WaitSemaphore failed\n");
+ fprintf(stderr, "PR_PostSemaphore failed\n");
exit(1);
}
}
@@ -134,7 +134,7 @@ int main(int argc, char **argv)
}
counter++;
if (PR_PostSemaphore(sem2) == PR_FAILURE) {
- fprintf(stderr, "PR_WaitSemaphore failed\n");
+ fprintf(stderr, "PR_PostSemaphore failed\n");
exit(1);
}
}
diff --git a/pr/tests/semaping.c b/pr/tests/semaping.c
index c5430aab..a00b9b42 100644
--- a/pr/tests/semaping.c
+++ b/pr/tests/semaping.c
@@ -85,7 +85,8 @@ int main(int argc, char **argv)
shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), PR_SHM_CREATE, SHM_MODE);
if (NULL == shm) {
- fprintf(stderr, "PR_OpenSharedMemory failed\n");
+ fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n",
+ PR_GetError(), PR_GetOSError());
exit(1);
}
counter_addr = PR_AttachSharedMemory(shm, 0);
@@ -102,7 +103,8 @@ int main(int argc, char **argv)
}
sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 0);
if (NULL == sem2) {
- fprintf(stderr, "PR_OpenSemaphore failed\n");
+ fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+ PR_GetError(), PR_GetOSError());
exit(1);
}
diff --git a/pr/tests/semapong.c b/pr/tests/semapong.c
index 932a7985..a91aa27b 100644
--- a/pr/tests/semapong.c
+++ b/pr/tests/semapong.c
@@ -65,7 +65,8 @@ int main(int argc, char **argv)
shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), 0, 0666);
if (NULL == shm) {
- fprintf(stderr, "PR_OpenSharedMemory failed\n");
+ fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n",
+ PR_GetError(), PR_GetOSError());
exit(1);
}
sem1 = PR_OpenSemaphore(SEM_NAME1, 0, 0, 0);
@@ -76,7 +77,8 @@ int main(int argc, char **argv)
}
sem2 = PR_OpenSemaphore(SEM_NAME2, 0, 0, 0);
if (NULL == sem2) {
- fprintf(stderr, "PR_OpenSemaphore failed\n");
+ fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+ PR_GetError(), PR_GetOSError());
exit(1);
}
diff --git a/pr/tests/server_test.c b/pr/tests/server_test.c
index 10e70bac..6553f439 100644
--- a/pr/tests/server_test.c
+++ b/pr/tests/server_test.c
@@ -160,8 +160,8 @@ WorkerThreadFunc(void *_listenSock)
char *sendBuf;
if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
- _client_data+(4*sizeof(PRNetAddr)), _client_data, (4*sizeof(PRNetAddr)));
- dataBuf = (char *)PR_MALLOC(_client_data *sizeof(char) + 4*sizeof(PRNetAddr));
+ _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));
diff --git a/pr/tests/servr_kk.c b/pr/tests/servr_kk.c
index 3a225ff1..7ad32922 100644
--- a/pr/tests/servr_kk.c
+++ b/pr/tests/servr_kk.c
@@ -126,8 +126,8 @@ WorkerThreadFunc(void *_listenSock)
char *sendBuf;
if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
- _client_data+(4*sizeof(PRNetAddr)), _client_data, (4*sizeof(PRNetAddr)));
- dataBuf = (char *)PR_MALLOC(_client_data *sizeof(char) + 4*sizeof(PRNetAddr));
+ _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));
diff --git a/pr/tests/servr_ku.c b/pr/tests/servr_ku.c
index 53a117fa..1c573ffe 100644
--- a/pr/tests/servr_ku.c
+++ b/pr/tests/servr_ku.c
@@ -127,8 +127,8 @@ WorkerThreadFunc(void *_listenSock)
char *sendBuf;
if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
- _client_data+(4*sizeof(PRNetAddr)), _client_data, (4*sizeof(PRNetAddr)));
- dataBuf = (char *)PR_MALLOC(_client_data *sizeof(char) + 4*sizeof(PRNetAddr));
+ _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));
diff --git a/pr/tests/servr_uk.c b/pr/tests/servr_uk.c
index ef20cf08..19206b57 100644
--- a/pr/tests/servr_uk.c
+++ b/pr/tests/servr_uk.c
@@ -129,8 +129,8 @@ WorkerThreadFunc(void *_listenSock)
char *sendBuf;
if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
- _client_data+(4*sizeof(PRNetAddr)), _client_data, (4*sizeof(PRNetAddr)));
- dataBuf = (char *)PR_MALLOC(_client_data *sizeof(char) + 4*sizeof(PRNetAddr));
+ _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));
diff --git a/pr/tests/servr_uu.c b/pr/tests/servr_uu.c
index b6fc3a8f..8b9bc47d 100644
--- a/pr/tests/servr_uu.c
+++ b/pr/tests/servr_uu.c
@@ -127,8 +127,8 @@ WorkerThreadFunc(void *_listenSock)
char *sendBuf;
if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
- _client_data+(4*sizeof(PRNetAddr)), _client_data, (4*sizeof(PRNetAddr)));
- dataBuf = (char *)PR_MALLOC(_client_data *sizeof(char) + 4*sizeof(PRNetAddr));
+ _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));
diff --git a/pr/tests/socket.c b/pr/tests/socket.c
index 87165193..316ec75c 100644
--- a/pr/tests/socket.c
+++ b/pr/tests/socket.c
@@ -130,6 +130,7 @@ 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;
int failed_already=0;
typedef struct buffer {
@@ -169,7 +170,7 @@ readn(PRFileDesc *sockfd, char *buf, int len)
int rem;
int bytes;
int offset = 0;
- int err, oserr;
+ int err;
PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
if (test_cancelio)
@@ -362,19 +363,23 @@ TCP_Server(void *arg)
/*
* Create a tcp socket
*/
- if ((sockfd = PR_NewTCPSocket()) == NULL) {
+ if ((sockfd = PR_OpenTCPSocket(server_domain)) == NULL) {
fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
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);
+
+ 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;
@@ -401,9 +406,15 @@ TCP_Server(void *arg)
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;
+ 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
@@ -413,11 +424,13 @@ TCP_Server(void *arg)
for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) {
+ DPRINTF(("TCP_Server: Accepting connection\n"));
if ((newsockfd = PR_Accept(sockfd, &netaddr,
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");
@@ -480,15 +493,18 @@ UDP_Server(void *arg)
/*
* Create a udp socket
*/
- if ((sockfd = PR_NewUDPSocket()) == NULL) {
+ if ((sockfd = PR_OpenUDPSocket(server_domain)) == NULL) {
fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n");
failed_already=1;
return;
}
memset(&netaddr, 0 , sizeof(netaddr));
- netaddr.inet.family = PR_AF_INET;
- netaddr.inet.port = PR_htons(UDP_SERVER_PORT);
- netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+ 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
@@ -514,16 +530,23 @@ UDP_Server(void *arg)
DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
netaddr.inet.ip, netaddr.inet.port));
- udp_server_addr = netaddr;
-
/*
* 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).
+ * netaddr.inet.ip because netaddr.inet.ip is returned
+ * as 0 (= PR_INADDR_ANY).
*/
- udp_server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
-
+ 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'
@@ -606,17 +629,14 @@ TCP_Client(void *arg)
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;
+ netaddr = cp->server_addr;
for (i = 0; i < num_tcp_connections_per_client; i++) {
- if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) {
+ 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());
@@ -712,7 +732,7 @@ UDP_Client(void *arg)
failed_already=1;
return;
}
- if ((sockfd = PR_OpenUDPSocket(PR_AF_INET)) == NULL) {
+ if ((sockfd = PR_OpenUDPSocket(client_domain)) == NULL) {
fprintf(stderr,"prsocket_test: PR_OpenUDPSocket failed\n");
failed_already=1;
return;
@@ -723,9 +743,12 @@ UDP_Client(void *arg)
* number
*/
memset(&netaddr, 0 , sizeof(netaddr));
- netaddr.inet.family = PR_AF_INET;
- netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
- netaddr.inet.port = PR_htons(0);
+ 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");
@@ -741,9 +764,7 @@ UDP_Client(void *arg)
DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
netaddr.inet.ip, netaddr.inet.port));
- netaddr.inet.family = cp->server_addr.inet.family;
- netaddr.inet.port = cp->server_addr.inet.port;
- netaddr.inet.ip = cp->server_addr.inet.ip;
+ netaddr = cp->server_addr;
if (cp->udp_connect) {
if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
@@ -894,7 +915,6 @@ TCP_Socket_Client_Server_Test(void)
return -1;
}
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;
@@ -2138,8 +2158,41 @@ main(int argc, char **argv)
#endif
PR_SetConcurrency(4);
/*
- * run client-server test with TCP
+ * 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;
@@ -2147,8 +2200,44 @@ main(int argc, char **argv)
printf("TCP_Socket_Client_Server_Test Passed\n");
test_cancelio = 0;
/*
- * run client-server test with UDP
+ * 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;
diff --git a/pr/tests/sockopt.c b/pr/tests/sockopt.c
index 0dca5b92..d4a3f6c6 100644
--- a/pr/tests/sockopt.c
+++ b/pr/tests/sockopt.c
@@ -100,9 +100,6 @@ PRIntn main(PRIntn argc, char *argv)
else
{
PRSockOption option;
- PRLinger linger;
- PRUint32 ttl = 20;
- PRBool boolean = PR_TRUE;
PRUint32 segment = 1024;
PRNetAddr addr;
@@ -112,76 +109,6 @@ PRIntn main(PRIntn argc, char *argv)
if (PR_FAILURE == rv) Failed("PR_Bind()", NULL);
for(option = PR_SockOpt_Linger; option < PR_SockOpt_Last; Incr(&option))
{
- void *value;
- PRInt32 *size;
- PRInt32 ttlsize = sizeof(ttl);
- PRInt32 segmentsize = sizeof(segment);
- PRInt32 booleansize = sizeof(boolean);
- PRInt32 lingersize = sizeof(linger);
-
- PRFileDesc *socket = udp;
- switch (option)
- {
- case PR_SockOpt_Linger: /* linger on close if data present */
- socket = tcp;
- linger.polarity = PR_TRUE;
- linger.linger = PR_SecondsToInterval(1);
- value = &linger;
- size = &lingersize;
- break;
- case PR_SockOpt_NoDelay: /* don't delay send to coalesce packets */
- case PR_SockOpt_Keepalive: /* keep connections alive */
- socket = tcp;
- case PR_SockOpt_Reuseaddr: /* allow local address reuse */
- value = &boolean;
- size = &booleansize;
- break;
-#ifndef WIN32
- case PR_SockOpt_MaxSegment: /* maximum segment size */
- socket = tcp;
-#endif
- case PR_SockOpt_RecvBufferSize: /* send buffer size */
- case PR_SockOpt_SendBufferSize: /* receive buffer size */
- value = &segment;
- size = &segmentsize;
- break;
-
- case PR_SockOpt_IpTimeToLive: /* time to live */
- value = &ttl;
- size = &ttlsize;
- break;
- case PR_SockOpt_Broadcast:
- value = &boolean;
- size = &booleansize;
- break;
- case PR_SockOpt_IpTypeOfService: /* type of service and precedence */
- case PR_SockOpt_AddMember: /* add an IP group membership */
- case PR_SockOpt_DropMember: /* drop an IP group membership */
- case PR_SockOpt_McastInterface: /* multicast interface address */
- case PR_SockOpt_McastTimeToLive: /* multicast timetolive */
- case PR_SockOpt_McastLoopback: /* multicast loopback */
- 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_SetSockOpt(socket, option, value, *size);
- if (PR_FAILURE == rv) Failed("PR_SetSockOpt()",
- tag[option]);
- }
- }
-
- rv = PR_GetSockOpt(socket, option, &value, size);
- if (PR_FAILURE == rv) Failed("PR_GetSockOpt()", tag[option]);
- }
- for(option = PR_SockOpt_Linger; option < PR_SockOpt_Last; Incr(&option))
- {
PRSocketOptionData data;
PRFileDesc *fd = tcp;
data.option = option;
diff --git a/pr/tests/thrpool_client.c b/pr/tests/thrpool_client.c
index d06930f3..46d93b0a 100644
--- a/pr/tests/thrpool_client.c
+++ b/pr/tests/thrpool_client.c
@@ -25,7 +25,6 @@
** Modification History:
*/
#include "primpl.h"
-#include "prtpool.h"
#include "plgetopt.h"
diff --git a/pr/tests/thrpool_server.c b/pr/tests/thrpool_server.c
index 0452a0a9..56efcce9 100644
--- a/pr/tests/thrpool_server.c
+++ b/pr/tests/thrpool_server.c
@@ -25,7 +25,6 @@
** Modification History:
*/
#include "primpl.h"
-#include "prtpool.h"
#include "plgetopt.h"
@@ -251,6 +250,27 @@ Serve_Client(void *arg)
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
@@ -273,6 +293,7 @@ TCP_Server(void *arg)
PRMonitor *sc_mon;
PRJob *jobp;
int i;
+ PRStatus rval;
/*
* Create a tcp socket
@@ -318,6 +339,28 @@ TCP_Server(void *arg)
"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
*/
@@ -363,12 +406,6 @@ TCP_Server(void *arg)
return;
}
- 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;
@@ -378,6 +415,13 @@ TCP_Server(void *arg)
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,
@@ -387,27 +431,6 @@ TCP_Server(void *arg)
}
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 void
TCP_Server_Accept(void *arg)
{
Server_Param *sp = (Server_Param *) arg;
diff --git a/pr/tests/thruput.c b/pr/tests/thruput.c
index f06c1694..bdc23c3f 100644
--- a/pr/tests/thruput.c
+++ b/pr/tests/thruput.c
@@ -294,9 +294,7 @@ static void Help(void)
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");
-#ifdef _PR_INET6
PR_fprintf(err, "\t-6 Use IPv6 (default: IPv4)\n");
-#endif /* _PR_INET6 */
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");
@@ -325,12 +323,9 @@ PRIntn main(PRIntn argc, char **argv)
case 'X': /* Use XTP as the transport */
protocol = 36;
break;
-#ifdef _PR_INET6
case '6': /* Use IPv6 */
domain = PR_AF_INET6;
- PR_SetIPv6Enable(PR_TRUE);
break;
-#endif /* _PR_INET6 */
case 's': /* initial_streams */
initial_streams = atoi(opt->value);
break;
diff --git a/pr/tests/tmoacc.c b/pr/tests/tmoacc.c
index 2fe746c4..f41ce8c1 100644
--- a/pr/tests/tmoacc.c
+++ b/pr/tests/tmoacc.c
@@ -188,10 +188,6 @@ PRIntn Tmoacc(PRIntn argc, char **argv)
PLOptState *opt = PL_CreateOptState(argc, argv, "dGb:t:T:R");
-#ifdef _PR_INET6
- PR_SetIPv6Enable(PR_TRUE);
-#endif
-
shared = PR_NEWZAP(Shared);
shared->debug = NULL;
diff --git a/pr/tests/tmocon.c b/pr/tests/tmocon.c
index d3bb9839..0fd83b3c 100644
--- a/pr/tests/tmocon.c
+++ b/pr/tests/tmocon.c
@@ -280,9 +280,6 @@ int Tmocon(int argc, char **argv)
PRInt32 dally = DEFAULT_DALLY, timeout = DEFAULT_TIMEOUT;
PLOptState *opt = PL_CreateOptState(argc, argv, "divGRh:m:s:t:T:D:");
-#ifdef _PR_INET6
- PR_SetIPv6Enable(PR_TRUE);
-#endif
shared = PR_NEWZAP(Shared);
shared->debug = 0;
diff --git a/pr/tests/vercheck.c b/pr/tests/vercheck.c
index b616ad2a..461e7316 100644
--- a/pr/tests/vercheck.c
+++ b/pr/tests/vercheck.c
@@ -33,21 +33,26 @@
#include <stdlib.h>
/*
- * This release (3.5) is backward compatible with all
- * the previous releases. It, of course, is compatible
- * with itself.
+ * This release (4.0) is compatible with itself.
*/
static char *compatible_version[] = {
- "2.1 19980529", "3.0", "3.0.1", "3.1", "3.1.1", "3.1.2", PR_VERSION
+ 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[] = {
- "3.5.1",
- "4.0", "4.0.3",
+ "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.0.1",
+ "4.1", "4.1.3",
"10.0", "11.1", "12.14.20"
};
diff --git a/pr/tests/version.c b/pr/tests/version.c
index b361a9c1..a6218ec8 100644
--- a/pr/tests/version.c
+++ b/pr/tests/version.c
@@ -24,6 +24,8 @@
#include "plerror.h"
#include "plgetopt.h"
+PR_IMPORT(const PRVersionDescription *) libVersionPoint(void);
+
PRIntn main(PRIntn argc, char **argv)
{
PRIntn rv = 1;