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